私はHibernateをSpringフレームワークと組み合わせて使用する傾向があり、それは宣言型のトランザクション境界機能(@Transactionalなど)です。
誰もが知っているように、休止状態はできるだけ非侵襲的で透明性を保つように努めていますが、関係を採用する場合、これは少し難しいことがわかりますlazy-loaded
。
透明度のレベルが異なるデザインの選択肢がいくつかあります。
- 関係を遅延ロードしないようにします(例:
fetchType=FetchType.EAGER)
- これは、遅延読み込みのアイデア全体をバイオライトします。
- を使用してコレクションを初期化する
Hibernate.initialize(proxyObj);
- これは、DAOへの比較的高い結合を意味します
- でインターフェースを定義することはできますが
initialize
、他の実装が同等のものを提供することは保証されていません。
- 永続
Model
オブジェクト自体にトランザクション動作を追加します(動的プロキシまたはを使用@Transactional
)- @Transactionalが永続オブジェクト自体で機能するようには見えませんでしたが、動的プロキシアプローチを試したことはありません。おそらくその休止状態が原因で、プロキシでの操作が行われています。
- トランザクションが実際に行われているときの制御の喪失
- 両方の怠惰/非怠惰なAPIを提供し、例えば、
loadData()
およびloadDataWithDeps()
- アプリケーションに、どのルーチンをいつ使用するかを強制的に認識させます。これも密結合です。
- メソッドオーバーフロー
loadDataWithA()
、、 ....、loadDataWithX()
byId()
操作 のみを提供するなどして、依存関係のルックアップを強制します- 非オブジェクト指向のルーチン、例えば、の多くを必要と
findZzzById(zid)
し、その後getYyyIds(zid)
の代わりに、z.getY()
- トランザクション間に大きな処理オーバーヘッドがある場合は、コレクション内の各オブジェクトを1つずつフェッチすると便利です。
- 非オブジェクト指向のルーチン、例えば、の多くを必要と
- DAOだけでなく、アプリケーションの一部を@Transactionalにします。
- ネストされたトランザクションに関する考えられる考慮事項
- トランザクション管理に適合したルーチンが必要です(例:十分に小さい)
- プログラムによる影響は小さいが、トランザクションが大きくなる可能性がある
- DAOに動的フェッチプロファイルを提供します。
loadData(id, fetchProfile);
- アプリケーションは、いつ使用するプロファイルを知っている必要があります
- AoPタイプのトランザクション。たとえば、操作をインターセプトし、必要に応じてトランザクションを実行します。
- バイトコード操作またはプロキシの使用が必要
- トランザクションが実行されるときの制御の喪失
- いつものように、黒魔術:)
オプションを逃しましたか?
lazy-loaded
アプリケーション設計における関係の影響を最小限に抑えるために、どのアプローチをお勧めしますか?
(ああ、WoTでごめんなさい)