@Startupを追加することをお勧めします @Singleton PostgreSQLデータベースへのJDBC接続を確立し、LISTENを使用するクラス およびNOTIFY キャッシュの無効化を処理します。
更新 :これは、pgqと無効化のためのワーカーのコレクションを使用する別の興味深いアプローチです。
無効化シグナリング
NOTIFYを送信する更新中のテーブルにトリガーを追加します エンティティが更新されるときはいつでも。 PostgreSQL 9.0以降では、このNOTIFY ペイロード(通常は行ID)を含めることができるため、キャッシュ全体を無効にする必要はなく、変更されたエンティティのみを無効にする必要があります。ペイロードがサポートされていない古いバージョンでは、無効化されたエントリをタイムスタンプ付きのログテーブルに追加して、ヘルパークラスがNOTIFYを取得したときにクエリを実行することができます。 、または単にキャッシュ全体を無効にします。
ヘルパークラスがLISTENになりました s NOTIFY トリガーが送信するイベント。 NOTIFYを取得したとき イベントの場合、個々のキャッシュエントリを無効にしたり(以下を参照)、キャッシュ全体をフラッシュしたりできます。 PgJDBCのlisten/notifyサポートを使用して、データベースからの通知をリッスンできます。 java.sql.Connectionで管理されている接続プールをアンラップする必要があります 基盤となるPostgreSQL実装にアクセスして、org.postgresql.PGConnectionにキャストできるようにします。 getNotifications()を呼び出します その上で。
LISTENの代替 およびNOTIFY 、タイマーで変更ログテーブルをポーリングし、問題テーブルでトリガーを使用して、変更された行IDと変更タイムスタンプを変更ログテーブルに追加できます。このアプローチは、DBタイプごとに異なるトリガーが必要な場合を除いて移植可能ですが、非効率的でタイムリーではありません。頻繁に非効率的なポーリングが必要になりますが、それでも、listen/notifyアプローチにはない時間遅延があります。 PostgreSQLでは、UNLOGGEDを使用できます このアプローチのコストを少し削減するための表。
キャッシュレベル
EclipseLink/JPAにはいくつかのレベルのキャッシュがあります。
第1レベルのキャッシュは、EntityManagerにあります レベル。エンティティがEntityManagerに接続されている場合 persist(...)による 、merge(...) 、find(...) など、次にEntityManager そのエンティティの同じインスタンスを返す必要があります 同じセッション内で再度アクセスされた場合、アプリケーションにまだ参照があるかどうかは関係ありません。データベースの内容が変更された場合、この接続されたインスタンスは最新ではありません。
オプションの第2レベルのキャッシュは、EntityManagerFactoryにあります。 レベルであり、より伝統的なキャッシュです。 2次キャッシュが有効になっているかどうかは不明です。 EclipseLinkログとpersistence.xmlを確認してください 。 EntityManagerFactory.getCache()を使用して、第2レベルのキャッシュにアクセスできます。; Cacheを参照してください 。
@thedayofcondorは、第2レベルのキャッシュを次のようにフラッシュする方法を示しました:
em.getEntityManagerFactory().getCache().evictAll();
ただし、evict(java.lang.Class cls, java.lang.Object primaryKey)を使用して個々のオブジェクトを削除することもできます。 電話:
em.getEntityManagerFactory().getCache().evict(theClass, thePrimaryKey);
@Startupから使用できます @Singleton NOTIFY 変更されたエントリのみを無効にするリスナー。
第1レベルのキャッシュは、アプリケーションロジックの一部であるため、それほど簡単ではありません。 EntityManagerがどのように機能するかを知りたいと思うでしょう 、アタッチおよびデタッチされたエンティティなどが機能します。 1つのオプションは、問題のテーブルに常にデタッチされたエンティティを使用することです。ここでは、新しいEntityManagerを使用します。 エンティティをフェッチするときはいつでも。この質問:
JPAEntityManagerセッションの無効化
エンティティマネージャのキャッシュの無効化の処理に関する有用な説明があります。ただし、EntityManagerが RESTful Webサービスは通常、短いEntityManagerを使用して実装されるため、キャッシュが問題になります。 セッション。これは、拡張永続コンテキストを使用している場合、または独自のEntityManagerを作成および管理している場合にのみ問題になる可能性があります。 コンテナ管理の永続性を使用するのではなく、セッション。