Java 未调用 JPA @PreUpdate

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21657978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:54:30  来源:igfitidea点击:

JPA @PreUpdate is not called

javajakarta-eejpa

提问by kboom

Could someone explain to me the reason of the following behavior?

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

EntityAis being first created and then persisted using em.persist(..)method. @PrePersistcallback is executed before the transaction ends. It works fine.

EntityA首先创建,然后使用em.persist(..)方法持久化。@PrePersistcallback 在事务结束前执行。它工作正常。

In the new transaction EntityAis obtained using em query. Then, some operations modifying its persistable fields are executed and this transaction ends. But on em.flush(), the @PreUpdatemethod is never called nor is @PrePersist(the latter I anticipated). Why?

在新交易EntityA中使用 em 查询获得。然后,执行一些修改其持久字段的操作,此事务结束。但是在 上em.flush(),该@PreUpdate方法从未被调用,也从未被调用@PrePersist(后者是我预料到的)。为什么?

// EDIT

// 编辑

That's the trace just before failure. "Done materializing entity" is the effect of the first operation in the transaction that fails.

那是失败前的痕迹。“完成实体化实体”是事务中第一个操作失败的结果。

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

Thanks!

谢谢!

回答by cmd

In the new transaction, @PrePersistwould be called if you performed a mergeto update EntityA's state. Simply modifying EntityA's persistent fields without a merge will not result in a call to @PrePersist

在新事务中,@PrePersist如果您执行了merge更新EntityA状态,将被调用。简单地修改EntityA没有合并的持久字段不会导致调用@PrePersist

It is similar for @PreUpdate, however is not guaranteed that the PreUpdatecallback is invoked when an entity is persisted and then modified in a single transaction (which is not the case in your example).

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

If you are using a transaction-scoped container-managed entity manager, then when a transaction ends, those entities become detached. This is likely what is happening when your first transaction completes. These detached entities will continue to live outside of the persistence context in which they were persisted, however the state of those entities are no longerguaranteed to be synchronized with the database. To ensure their state is synchronized, you should perform a mergein your second transaction. This will cause the resulting entity to be managed by the persistence context and thus able to be synchronized with the database.

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

If you don't like this behavior you can choose to use an extended persistence context.

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