有人可以向我解释以下行为的原因吗?
首先创建 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
谢谢!
答案 0 :(得分:4)
在新的交易中,如果您执行@PrePersist
更新merge
的状态,则会调用EntityA
。简单地修改EntityA
的持久字段而不合并将不会导致调用@PrePersist
@PreUpdate
类似,但不保证在实体持久化并在单个事务中修改后调用PreUpdate
回调(在您的示例中不是这种情况)。
如果您使用的是事务范围的容器管理的实体管理器,那么当事务结束时,这些实体将被分离。这可能是您的第一个交易完成时发生的情况。这些分离的实体将继续存在于持久化的持久性上下文之外,但这些实体的状态不再保证与数据库同步。要确保其状态同步,您应在第二个事务中执行merge
。这将导致生成的实体由持久性上下文管理,从而能够与数据库同步。
如果您不喜欢此行为,则可以选择使用扩展持久性上下文。