Jpa和Hibernate是否加载在DB中异步更改的数据?

我有一个oracle视图,我在其中查询我的数据库。

create or replace view my_view as Select cc.CCID ccid sm.SMCODE smcode, NVL(sm.smname, cc.ccname) sname From CC cc Inner Join SM sm On cc.id = sm.id; 

我使用jpa 2.1hibernate 4.3.7将我的视图映射到我的实体。 我的实体类看起来像这样:

 public class CCRequest implements Serializable { private static final long serialVersionUID = 1L; private String ccId; private String smCode; private String sName; } 

我的映射xml看起来像这样:

    

所以我正确地用jpa查询我的实体,它返回我的所有记录。 这是问题,当我异步更改数据库中的数据时,我的jpa查询返回先前的记录。 我做错了什么吗?

Hibernate缓存以前的结果,因此您应该使用entityManager.clear()来清理相关的缓存。 它将强制再次执行查询。 相关主题的更多细节:

  • 何时使用EntityManager.clear()?
  • 我应该经常调用EntityManager.clear()来避免内存泄漏吗?
  • Hibernate不会完全刷新实体子元素

有关Hibernate缓存的更多信息:

  • 什么是Hibernate中的一级和二级缓存?
  • 如何禁用hibernate缓存

另一种选择是使用entityManager.refresh(obj)将数据库数据与会话数据同步。

不是那么令人震惊JPA对其他进程更新数据库没有先见之明的知识,怎么可能呢? 你是唯一知道这一点的人,所以必须使用

 em.refresh(obj) 

如果您知道(可能)已更改数据,则更新对象。

我面临的问题是,在4之前的spring,我们JpaTemplate处理jpa实体,我从EntityManager实例以编程方式将EntityManager传递给JpaTemplate实例,没有任何问题。

JpaTemplate本身可以做任何事情来刷新EntityManager和清除缓存。 当我迁移到Spring 4时,我遇到了JpaTemplate已被删除所以我必须直接使用EntityManager

我从EntityManager的实例以编程方式获取EntityManager的实例。

我有一个EntityManagerProvider类,它从EntityManager的一个实例创建一个EntityManager实例。

 public class EntityManagerProvider { public static EntityManager createEntityManager(EntityManagerFactory entityManagerFactory) { return entityManagerFactory.createEntityManager(); } } 

我得到这样的entityManager实例:

    

但据我所知,如果我希望EntityManager管理事务和刷新,唯一的方法是使用@PersistenceContextEntityManager注入我的bean。

 @PersistenceContext protected EntityManager em; 

我对这种方式感到有些困惑,但这个问题解决了我的问题。