1

Web アプリケーションでは、JPA エンティティを使用して、ドメイン オブジェクトを基礎となるデータベースとの間で永続化 (および取得) しています。 これらの JPA エンティティは、Web アプリケーションの実行時間全体にわたって、メモリ内キャッシュ構造 ( と考えてください) で「ホット」に保たれMap<UniqueID, Entity>ます。

Web アプリケーションにリクエストを送信すると、リポジトリからエンティティが読み込まれます。このエンティティは、メモリ内キャッシュ構造に配置されます。このリクエストの存続期間中、このエンティティの任意のフィールドに問題なくアクセスできます。この最初のリクエストでは、他のエンティティへのリレーションシップの遅延読み込みも正常View機能しますOpenEntityManagerInViewInterceptor

最初のリクエストは終了しました。

Web アプリケーションに対して次の要求を行っています。このリクエストは、別のエンティティを要求します。このエンティティは既にメモリ内キャッシュ構造にあるため、そこから読み込まれます。このエンティティから、他のエンティティへのリレーションシップを遅延ロードする必要があるフィールドにアクセスしようとします。残念ながら、これは不快な原因になります org.hibernate.LazyInitializationException: could not initialize proxy - no Session(私は基礎となるJPA実装としてHibernateを使用しています)

私の理解では、この例外は、最初のリクエストが終了した後、JPA/Hibernate が JPA セッションを終了したにもかかわらず、メモリ内キャッシュ構造内のエンティティがこれらのセッションのいずれかが存在することを期待しているという事実に起因しています。次のリクエストによって遅延読み込みエンティティのメカニズムが起動された時点で、遅延読み込みメカニズムは存在しないセッションを見つけることができません。

私の問題の解決策は何ですか?

4

3 に答える 3

2
  1. 解決策の 1 つは、 を使用して 2 番目のリクエストの開始時にエンティティをセッションに再アタッチすることSession.update()です。
  2. もう 1 つの解決策は、独自のソリューションではなく、Hibernateの2 次キャッシュを使用することです。自作のキャッシング メカニズムよりもはるかに信頼性が高いはずです。
于 2013-01-29T13:25:15.187 に答える
0

基本的に、HTTPリクエスト間でセッションを存続させることはできません。これは、リクエスト間でトランザクションを開いたままにすることを意味するためです。

唯一の解決策(ロードされているものとロードされていないものを自分で検出することは別として)は、エンティティ全体をフェッチしてからキャッシュに入れることだと思います。私見では、部分的にロードされたオブジェクトをキャッシュに入れてはいけません。オブジェクト全体を初めてロードしたくない場合は、オブジェクトの関係に個別のキャッシュを使用できます。

必要に応じて、@ Adamによって提案されたHibernateキャッシュを有効にすることも検討できますが、女性がロードしたフィールドではうまく機能しないと思います。

于 2013-01-29T13:28:41.687 に答える
0

オブジェクトが現在のセッションから切り離されているため、この例外が発生しています。評価する前に、このオブジェクトを現在のセッションに再接続する必要があります

session.update(object);

ここで詳細を読むことができます

于 2013-01-29T13:32:45.483 に答える