【发布时间】:2017-11-09 08:42:45
【问题描述】:
我正在为 JPA 使用 Eclipselink,并且有一个 Web 应用程序可以在配置的时间间隔内读取表格。数据库通过工具在外部进行修改以发布一些数据。现在我的 webapp 在一个实体上创建一个 getAll() 并将结果作为一个列表。但是,每次我得到与第一个查询相同的结果列表时。令人惊讶的是,新条目和已删除条目会按预期反映在结果列表中。如果我更新一个条目,它仍然会得到原始/旧的结果。
从我的搜索来看,stackoverflow中的大部分答案都指向了JPA级别的缓存,可以总结为这些
- 通过设置禁用共享缓存
<shared-cache-mode>NONE</shared-cache-mode> - (可选)使用
@Cacheable(false)选择性地禁用实体上的缓存 - 通过
em.getEntityManagerFactory().getCache().evictAll()清除缓存 - 还有一些其他/旧/pre-JPA 2.0 和供应商特定的解决方案在 persistence.xml 中设置了一些属性
但是,这些解决方案都不适用于我的情况。我遇到的最接近的答案是this, which says that
会话缓存中已存在的任何 ID 都与已知实体匹配,而任何未根据数据库状态填充的 ID。以前已知的实体根本不会从数据库中刷新。
虽然这是在 Hibernate 的上下文中,但我在 Eclipselink 中遇到了同样的问题。因此,在列表中引入刷新后,我得到了预期的结果。
T objects = getAll();
for (T objects : object)
em.refresh(object)
List<T> getAll() {
EntityManager em = entityManagerFactory.createEntityManager();
return em.createQuery(em.getCriteriaBuilder().createQuery(type)).getResultList();
}
有人可以在 Eclipselink 的上下文中解释这个Session cache,并解释为什么shared-cache 配置对此没有影响吗?事务是否透明地解决了这个问题(读取事务)?有没有比每次都刷新对象更优雅的解决方案/JPA 配置?
【问题讨论】:
标签: java hibernate jpa eclipselink jpa-2.0