JPA @PreUpdate未被调用

时间:2014-02-09 10:33:41

标签: java java-ee jpa

有人可以向我解释以下行为的原因吗?

首先创建

EntityA,然后使用em.persist(..)方法保留。在事务结束之前执行@PrePersist回调。它工作正常。

在新事务EntityA中使用em查询获取。然后,执行修改其可持久字段的一些操作,并且该事务结束。但是在em.flush()上,@PreUpdate方法永远不会被调用,也不是@PrePersist(我预期的后者)。为什么?

//编辑

那是失败前的痕迹。 "完成实体实体"是失败的事务中第一个操作的影响。

DEBUG: org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [com.example.entity#1]
DEBUG: org.hibernate.event.internal.AbstractFlushingEventListener - Processing flush-time cascades
DEBUG: org.hibernate.ejb.AbstractEntityManagerImpl - Mark transaction for rollback
DEBUG: org.springframework.orm.jpa.JpaTransactionManager - Initiating transaction rollback
DEBUG: org.springframework.orm.jpa.JpaTransactionManager - Rolling back JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@341a736]
DEBUG: org.hibernate.engine.transaction.spi.AbstractTransactionImpl - rolling back
DEBUG: org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - rolled JDBC Connection

谢谢!

1 个答案:

答案 0 :(得分:4)

在新的交易中,如果您执行@PrePersist更新merge的状态,则会调用EntityA。简单地修改EntityA的持久字段而不合并将不会导致调用@PrePersist

@PreUpdate类似,但不保证在实体持久化并在单个事务中修改后调用PreUpdate回调(在您的示例中不是这种情况)。

如果您使用的是事务范围的容器管理的实体管理器,那么当事务结束时,这些实体将被分离。这可能是您的第一个交易完成时发生的情况。这些分离的实体将继续存在于持久化的持久性上下文之外,但这些实体的状态不再保证与数据库同步。要确保其状态同步,您应在第二个事务中执行merge。这将导致生成的实体由持久性上下文管理,从而能够与数据库同步。

如果您不喜欢此行为,则可以选择使用扩展持久性上下文