Hibernate を Spring フレームワークと組み合わせて使用する傾向があり、それは宣言的なトランザクション境界設定機能です(例: @ Transactional )。
よく知られているように、休止状態は可能な限り非侵襲的および透明にしようとしますが、これはもう少し挑戦的ですlazy-loaded
関係を使用する場合。
さまざまなレベルの透明度を持つ多くのデザインの選択肢があります。
fetchType=FetchType.EAGER)
Hibernate.initialize(proxyObj);
を使用してコレクションを初期化しますinitialize
を使用してインターフェイスを定義できますが、他の実装では同等のものを提供することは保証されません。Model
オブジェクト自体にトランザクション動作を追加します( dynamic proxy または@Transactional
)を使用します。loadData()
とloadDataWithDeps()
)loadDataWithA()
、....、loadDataWithX()
byId()
操作のみを提供することにより、依存関係の検索を強制しますfindZzzById(zid)
が必要で、その後getYyyIds(zid)
の代わりにz.getY()
が必要ですloadData(id, fetchProfile);
)オプションがありませんか?
アプリケーション設計でlazy-loaded
関係の影響を最小限にしようとする場合、どのアプローチが望ましいですか?
(ああ、 WoT でごめんなさい)
周知のように、休止状態は可能な限り非侵襲的かつ透過的になるように努めます
最初の仮定は間違っていると思います。アプリケーションは常にエンティティのライフサイクルとロードされるオブジェクトグラフのサイズを処理する必要があるため、Transaparent persistenceは神話です。
Hibernateは思考を読み取ることができないため、特定の操作に特定の依存関係セットが必要であることがわかっている場合は、何らかの方法でHibernateに意図を表現する必要があります。
この観点から、これらの意図を明示的に表現するソリューション(つまり、2、4、および7)は合理的に見え、透明性の欠如に悩まされません。
どの問題(遅延が原因)が示唆されているのかわかりませんが、私にとって最大の苦痛は、自分のアプリケーションキャッシュでセッションコンテキストが失われないようにすることです。典型的なケース:
foo
がロードされ、マップに配置されます。foo.getBar()
(以前に呼び出されたことがなく、遅延評価されるもの)を呼び出します。したがって、これに対処するために、いくつかのルールがあります。
OpenSessionInViewFilter
)。try/finally
)したがって、サブクラスはそれについて考える必要がありません。ご覧のとおり、これは確かに非侵襲的で透過的に近いところはありません。しかし、熱心なローディングのために私が支払わなければならない価格と比較するために、コストはまだ耐えられます。後者の問題は、エンティティのコレクションはもちろんのこと、単一の参照オブジェクトをロードするときに、バタフライ効果につながる場合があることです。メモリ消費、CPU使用率、そして控えめに言ってもレイテンシーもはるかに悪いので、私はそれに耐えることができると思います。
非常に一般的なパターンは、Webアプリケーションを構築する場合に OpenEntityManagerInViewFilter を使用することです。
サービスを構築している場合、メソッドは複数のエンティティを取得または更新する必要があることが多いため、DAOではなくサービスのパブリックメソッドでTXを開きます。
これにより、「遅延ロード例外」が解決されます。パフォーマンスチューニングのためにより高度なものが必要な場合は、フェッチプロファイルが最適な方法だと思います。