長時間実行される会話 (JPA/Hibernate および Seam 2.2 を使用) での第 1 レベルのキャッシュに問題があります。
長時間実行される会話を使用する検索ページがあります (いくつかの ajax インタラクション、モーダルでの編集などに必要です)。
問題は、別のユーザーがエンティティを変更したときに、ユーザーが検索ボタンを再度クリックしたときに変更が表示されないことです。ここで同様の問題を参照してください
そのため、長時間実行されている会話エンティティは第 1 レベルのキャッシュから読み込まれますが、各エンティティで手動で更新を呼び出さない限り、他のトランザクションで行われた変更は読み込まれません。
CacheMode.IGNORE または CacheMode.REFRESH (hibernate クエリ経由) を使用しようとしましたが、2 番目のレベルのキャッシュのみを処理するため、問題は解決しません。
選択クエリがデータベースに送信されていることがわかりますが、Hibernate はまだ第 1 レベルのキャッシュにキャッシュされたオブジェクトを使用しているようです。
新しい検索を行う前に以前の検索からエンティティを削除しようとしましたが、それはうまくいきましたが、後で削除されたエンティティを指しているオブジェクトがまだセッションにあったため、有線の問題に遭遇していました。追加する必要があります
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.EVICT,org.hibernate.annotations.CascadeType.REFRESH})
エンティティの関係についてですが、見逃すのは簡単です。
ホール セッションをクリアすることもできますが、それによって LazyInitializationErrors が発生する可能性があります。
クエリで第 1 レベルのキャッシュを使用しないように JPA/Hibernate に指示する方法はありませんか?
編集:なぜうまくいかないのかという良い答えがありますが、各エンティティを更新するという提案は理想的ではありません。以前にこれを使用したことがありますが、問題は、たとえば 200 エントリのリストの場合、データベースに対して 200 の個別のロードが生成され、非常に遅くなることです。これら 200 のエントリのうち、変更された可能性があるのは 1 つまたは 2 つだけです。では、どのエンティティが変更されたかをどのように識別しますか! 変更ごとに更新されるエンティティにタイムスタンプを使用すると、それを使用できると思います。前回の検索のタイムスタンプを記録し、その後変更されたリスト内のエンティティを検索します。もっとエレガントなソリューションはありますか?