加载数据,避免在持久化上下文中找到的实体

时间:2012-10-15 11:51:56

标签: java hibernate postgresql jpa persistence

我想执行一个方法(compareEntities),它需要当前在数据库中的实体和刚刚保存的对象。在我的DAO中这样的东西,其中em是EntityManager:

public void save(MyObj myObj) {
    MyObj previous = null;
    MyObj current = null;
    Integer id = myObj.getId();     
    if (id == null) {
        // new
        current = em.persist(myObj);
    } else {
        previous = em.find(MyObj.class, id);
        // update
        current = em.merge(myObj);
    }
    compareEntities (previous, current);
}

问题在于,由于要保存的实体来自数据库并且我对其进行了一些更改,当我尝试从数据库中获取数据时(使用find方法)我得到了数据因为实体是在持久化上下文中找到的。有没有办法在没有我对同一事务中的实体所做的更改的情况下获取数据库中的数据?

感谢。

1 个答案:

答案 0 :(得分:1)

使用具有当前附加的同一实体的已修改实例的持久性上下文,没有可靠的方法来查找未更改的实体。持久性提供程序可能已将更改刷新到数据库,在这种情况下,后续SELECT将显示已更改的对象,因为这是事务中的当前内容。即使持久性提供程序尚未刷新更改,规范也需要从同一密钥的find调用返回相同实例。不允许返回“未更改”的对象。

您需要使用其他连接从新事务中获取数据。如何做到这一点取决于您的编程模型。在具有容器管理事务(如EJB3)的JTA编程模型中,您将使用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)带注释的业务方法。在普通的JPA中,你会得到一个新的EntityManager和find ID对象。

我怀疑您正在尝试实施审核日志系统,在这种情况下,您应该查看Hibernate Envers,PostgreSQL audit trigger example或标准JPA实体监听器,所有这些都提供了更好的方法完成这项任务。尝试解释你试图解决的根本问题,这个问题的“为什么”是“如何”。