Hibernate の第 2 レベルのキャッシュを使用してデータベース ヒットを回避するアプリケーションがあります。
MySQL 管理者などの外部プロセスが直接接続してデータベースを変更 (更新/挿入/削除) したときに、Java アプリケーションの Hibernate 2nd レベル キャッシュを無効にする簡単な方法があるかどうか疑問に思っていました。
2 番目のレベルのキャッシュの実装としてEHCacheを使用しています。
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) と @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) を組み合わせて使用し、各エンティティのタイムスタンプを使用してオプティミスティック同時実行制御を有効にしません。
SessionFactory には、第 2 レベルのキャッシュを管理するためのメソッドが含まれています。 - キャッシュの管理
sessionFactory.evict(Cat.class, catId); //evict a particular Cat
sessionFactory.evict(Cat.class); //evict all Cats
sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections
しかし、個々のエンティティ クラスに @Cache でアノテーションを付けているため、それを「確実に」(たとえば、手動の手順なしで) リストに追加する中心的な場所がありません。
// Easy to forget to update this to properly evict the class
public static final Class[] cachedEntityClasses = {Cat.class, Dog.class, Monkey.class}
public void clear2ndLevelCache() {
SessionFactory sessionFactory = ... //Retrieve SessionFactory
for (Class entityClass : cachedEntityClasses) {
sessionFactory.evict(entityClass);
}
}
Hibernate の第 2 レベルのキャッシュがエンティティを照会しない限り、DB でエンティティが変更されたことを知る本当の方法はありません (これはキャッシュがあなたを保護しているものです)。したがって、解決策として、単純にメソッドを呼び出して、第 2 レベルのキャッシュにすべてを強制的に追い出すことができます (これも、ロックと同時実行制御が不足しているため、進行中のトランザクションが古いデータを「読み取ったり更新したりするリスクがあるためです)」。