1

我想执行一个方法(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 方法)时,我得到了更改后的数据因为实体是在持久化上下文中找到的。有什么方法可以获取数据库中的数据,而无需我对同一事务中的实体所做的更改?

谢谢。

4

1 回答 1

1

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

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

我怀疑您正在尝试实现审计日志系统,在这种情况下,您应该查看Hibernate Envers、PostgreSQL审计触发器示例或标准 JPA 实体侦听器,所有这些都提供了更好的方法来完成此任务。试着解释你试图解决的根本问题,这个问题的“为什么”是“如何”。

于 2012-10-17T05:32:55.133 回答