Jpa&Hibernate是否加载数据库中异步变化的数据?

Do Jpa& Hibernate load data which changes asynchronously in 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 将我的视图映射到我的实体。 我的实体 class 看起来像这样:

public class CCRequest implements Serializable {

    private static final long serialVersionUID = 1L;

    private String ccId;

    private String smCode;

    private String sName;
}

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

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
                 version="2.1">
    <entity class="CCRequest" name="CCRequest001">
        <table name="my_view"/>
        <attributes>
            <id name="ccId">
                <column name="ccid"/>
            </id>
            <basic name="smCode">
                <column name="smcode"/>
            </basic>
            <basic name="sName">
                <column name="sname"/>
            </basic>
        </attributes>
    </entity>
</entity-mappings> 

所以我用 jpa 正确查询了我的实体,它 returns 我所有的记录。 这是问题所在,当我异步更改数据库中的数据时,令人震惊的是我的 jpa 查询 returns 以前的记录。 我是不是做错了什么?

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

em.refresh(obj)

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

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

  • When to Use EntityManager.clear()?
  • Am I supposed to call EntityManager.clear() often to avoid memory leaks?

关于 Hibernate 缓存的更多信息:

  • What are First and Second Level caching in Hibernate?
  • How to disable hibernate caching

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

我面临的问题是,在 4 之前的 spring 中,我们有 JpaTemplate 用于处理 jpa 实体,我将 EntityManager 传递给 [=13= 的实例] 以编程方式从 EntityManagerFactory 的实例中毫无问题。

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

我从 EntityManagerFactory.

的实例以编程方式获取 EntityManager 的实例 我有一个 EntityManagerProvider class 从 EntityManagerFactory.

的实例创建 EntityManager 的实例
public class EntityManagerProvider {

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

我得到这样的 entityManager 实例:

<bean id="entityManager" class="com.tosan.novin.sipa.bo.da.jpa.EntityManagerFactoryProvider" factory-method="createEntityManager">
        <constructor-arg index="0" ref="entityManagerFactory"/>
</bean>

但我明白,如果我想 EntityManager 管理事务和刷新,唯一的方法是使用 @PersistenceContextEntityManager 注入我的 bean。

@PersistenceContext
protected EntityManager em;

我对这种方式有点困惑,但我的问题用这种方法解决了。