JPAを使用したWebアプリケーションがあります。このエンティティマネージャーは多数のエンティティを保持しており、突然、反対側からデータベースを更新します。 MySQLを使用し、PhpMyAdminを使用して行を変更します。
エンティティマネージャに再同期を指示する方法(例:キャッシュ内のすべてのエンティティを忘れましたか?
私はrefresh(Object)
メソッドがあることを知っていますが、refreshAll()
またはこれをもたらす何かを行う方法はありますか?
これは確かに高価な操作ですが、実行する必要がある場合は確かです。
entityManager.getEntityManagerFactory().getCache().evictAll()
Refresh
は、オブジェクトを変更するであるため、異なるものです。この行はempty the cache
。したがって、エンティティマネージャーの外部で変更されたオブジェクトをフェッチすると、古いcached
値を使用する代わりに、実際のデータベースクエリが実行されます。
同様の問題があり、上記のevictAll()
行が機能しました。
または、@Cache
エンティティクラスのアノテーションも機能し、キャッシュパラメータを制御できるという利点があります。
@Cache(coordinationType=CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS)
参照: http://wiki.Eclipse.org/EclipseLink/Examples/JPA/Caching
まあ、factory.getCache()。evictAll();を追加しようとしたが動作しない、JPA + Hibernateを使用してクエリを更新する一部の人々(私のような)にヒントを追加するorg.hibernate.cacheMode to [〜#〜] ignore [〜#〜]例:
em.createNamedQuery("SomeEntity.SomeNamedQuery")
.setHint("org.hibernate.cacheMode", "IGNORE")
.getResultList();
Hibernateの代わりにEclipseLinkを使用している場合、ヒントは次のとおりです。
em.createNamedQuery("SomeEntity.SomeNamedQuery")
.setHint(QueryHints.REFRESH, true)
.getResultList();
cache.evictAllが機能していません。したがって、別のアプリからプッシュされたデータを取得するには、次のようにします。
em.getTransaction().begin();
em.getTransaction().commit();
その後、検索クエリは更新されたデータを取得します。それが非常に安全なソリューションであるかどうかはわかりませんが、適切に機能します。
オブジェクトをEntityManagerに読み込むと、永続化コンテキストの一部になり、clear()して新しいEntityManagerを取得するまで、同じオブジェクトがEntityManagerに残ります。したがって、データベースを更新する場合、オブジェクトでrefresh()を呼び出すか、EntityManagerをclear()しない限り、EntityManagerは変更を認識しません。これは、共有キャッシュ(L2)または永続コンテキスト(L1)とは関係ありません。共有キャッシュも使用し、データベースを直接更新する場合、共有キャッシュは古くなっています。オブジェクトをrefresh()するか、次に照会するときに更新するために無効としてマークする必要があります。
コードは次のような方法に従う必要があります。リフレッシュマージフラッシュのデタッチ