首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么JPA实体刷新是必需的,尽管禁用共享缓存?

为什么JPA实体刷新是必需的,尽管禁用共享缓存?
EN

Stack Overflow用户
提问于 2017-06-07 20:18:59
回答 2查看 2.3K关注 0票数 1

对于JPA,我使用Eclipselink,并且有一个webapp,它在配置的时间间隔内读取表。数据库由一个工具进行外部修改,以发布某些数据。现在,我的webapp在实体上创建了一个getAll(),并以列表的形式获取结果。但是,每次我得到的结果列表与第一个查询的结果列表相同。令人惊讶的是,新条目和已删除条目按预期反映在结果列表中。如果我更新一个条目,它仍然会得到原始/旧的结果。

根据我的搜索,堆栈溢出点中的大多数答案都指向JPA级别的缓存,可以归纳为

  • 通过设置<shared-cache-mode>NONE</shared-cache-mode>禁用共享缓存
  • 或者,使用@Cacheable(false)选择性地禁用实体上的缓存
  • 通过执行em.getEntityManagerFactory().getCache().evictAll()删除缓存
  • 还有其他一些/旧/预JPA2.0和特定于供应商的解决方案,这些解决方案在persistence.xml中设置了一些属性

然而,这些解决方案都不适用于我的情况。我遇到的最接近的答案是这个,上面写着

会话缓存中已经存在的任何in都与已知实体相匹配,而不存在的任何in则基于数据库状态填充。以前已知的实体根本不会从数据库中刷新。

虽然这是在Hibernate的上下文中,但我在Eclipselink中遇到了同样的问题。因此,在对列表进行刷新之后,我得到了预期的结果。

代码语言:javascript
复制
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配置比每次对对象进行刷新更好?

EN

回答 2

Stack Overflow用户

发布于 2017-06-10 04:14:54

从JPA2.0开始,您可以使用查询提示绕过或刷新缓存。

代码语言:javascript
复制
Query query = entitymanager.createQuery("select student FROM Student student");
query.setHint("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS);

这里是一个很好的解释

票数 2
EN

Stack Overflow用户

发布于 2017-06-08 16:01:11

您提到的所有内容都涉及到共享缓存,但是JPA中有两个级别的缓存。共享缓存(2级)和EntityManager管理实体缓存(1级)。EntityManagers用于表示事务性工作区。您应该在适当的地方获得新的Entitymanager实例,而不是对所有东西使用单个实例,或者调用它上的em.clear()来释放资源。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44422070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档