EntityManager刷新

时间:2011-04-29 13:04:25

标签: java jpa entitymanager

我有使用JPA的Web应用程序。这个实体管理器保留了大量的实体,突然间我从另一侧更新了数据库。我使用 MySQL ,我使用 PhpMyAdmin 并更改了一些行。

如何告诉实体经理重新同步,例如忘记缓存中的所有entites?

我知道有refresh(Object)方法,但是有可能如何做refreshAll()或其中的结果吗?

这肯定是昂贵的操作,但是如果必须这样做的话。

6 个答案:

答案 0 :(得分:35)

entityManager.getEntityManagerFactory().getCache().evictAll()

Refresh因为修改您的对象而有所不同。这一行只有empty the cache,因此如果您获取在实体管理器外部更改的对象,它将执行实际的数据库查询,而不是使用过时的cached值。

答案 1 :(得分:7)

我有一个类似的问题,上面的evictAll()行为我工作。

或者,实体类的@Cache注释也可以工作,并且能够控制缓存参数:

@Cache(coordinationType=CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS)

请参阅:http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching

答案 2 :(得分:3)

好吧,对于那些尝试添加 factory.getCache()。evictAll(); 并且不起作用并且使用JPA + Hibernate来刷新查询的人(比如我)将提示 org.hibernate.cacheMode 添加到 IGNORE 。例如:

em.createNamedQuery("SomeEntity.SomeNamedQuery")
  .setHint("org.hibernate.cacheMode", "IGNORE")
  .getResultList();

答案 3 :(得分:2)

cache.evictAll对我不起作用。因此,为了检索从另一个应用程序推送的数据,我执行:

em.getTransaction().begin();
em.getTransaction().commit();

之后,我的查询查询检索刷新的数据。我不知道它是否是非常安全的解决方案,但它运作正常。

答案 4 :(得分:2)

如果您使用的是EclipseLink而不是Hibernate,则提示是:

em.createNamedQuery("SomeEntity.SomeNamedQuery")
.setHint(QueryHints.REFRESH, true)
.getResultList();

答案 5 :(得分:0)

当您将对象读入EntityManager时,它将成为持久化上下文的一部分,并且同一个对象将保留在EntityManager中,直到您清除()它并获取新的EntityManager。 因此,如果更新数据库,除非您在对象上调用refresh()或清除()EntityManager,否则EntityManager将看不到更改。这与共享缓存(L2)或持久性上下文(L1)无关。如果您还使用共享缓存并直接更新数据库,那么您的共享缓存将过时。您需要刷新()对象,或将其标记为无效,以便在下次查询时刷新。

代码必须遵循这样的方式。 分离 REFRESH 合并 FLUSH