我想执行一个方法 (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 方法)我获取了数据进行更改,因为实体是在持久性上下文中找到的。有什么方法可以获取数据库中的数据,而无需我对同一事务中的实体所做的更改?
谢谢。
最佳答案
没有可靠的方法可以使用当前附加了同一实体的修改实例的持久性上下文来查找未更改的实体。持久性提供程序可能已将更改刷新到数据库,在这种情况下,后续的 SELECT
将显示changed 对象,因为这是事务中的当前对象。即使持久性提供程序尚未刷新更改,规范要求从 find
调用返回相同的实例同一个键。不允许返回“未更改”的对象。
您将需要使用另一个连接从新事务中获取数据。如何做到这一点取决于您的编程模型。在具有容器管理事务的 JTA 编程模型(如 EJB3)中,您将使用带注释的 @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
业务方法。在普通 JPA 中,您将获得一个新的 EntityManager 并通过 ID 查找
对象。
我怀疑您正在尝试实现审计日志系统,在这种情况下您应该查看 Hibernate Envers , PostgreSQL audit trigger example ,或标准的 JPA 实体监听器,所有这些都提供了更好的方法来完成此任务。尝试解释您要解决的根本问题,即此问题的“方法”的“原因”。
关于java - 加载数据避免在持久性上下文中找到的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12895079/