私はSpringフレームワークと組み合わせてHibernateを使用する傾向があり、それは宣言型のトランザクション境界機能(@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でごめんなさい)