【问题标题】:Lifecycle callbacks on detached entity not called when merged back合并回来时未调用分离实体上的生命周期回调
【发布时间】:2017-01-17 01:32:58
【问题描述】:

我在 JPA 项目中观察到意外行为。

基本上,我的实体在每次更新时都会调用其modified() 方法,如下所示:

@PrePersist
@PreUpdate
private void callback() {
    modified(); // sets a java.util.time.Instant
}

正常工作。

在某些时候,我不得不分离实体,进行一些更改,然后将其合并回来;但没有调用回调。

这是一个错误,还是文档规范的一部分?

如果重要的话,我正在使用 EclipseLink。


编辑:将其追踪到一个完全不同的问题,这与这个问题无关。

【问题讨论】:

  • 您能否将您的事务方法附加到执行所有操作(包括合并)的位置?可能会对事情有所了解

标签: java jpa orm


【解决方案1】:

好的,我做了一些测试,这就是我的发现和我对这个案例的看法(我使用 JPA 2.1)。

merge() 操作可以调用事件侦听器的唯一一次是在尚未持久化的新实体上调用它。然后它本身充当persist() 操作,并调用@PrePersist 注释类。 这是规范的正确行为:

PrePersistPreRemove 回调方法是针对给定的 EntityManager persistremove 之前的实体 执行该实体的操作。对于实体 已应用合并操作并导致创建新的 托管实例,PrePersist 回调方法将被调用 实体状态复制到它之后的托管实例。

现在你正在做的是修改已经存在的实体,唯一可以调用的监听器是@PreUpdate / @PostUpdate。 尽管按照规范,您有:

请注意,PreUpdate 和 PostUpdate 回调发生在实体被持久化并且 随后在单个交易中修改或当实体被修改时 修改并随后在单个事务中删除。 便携式应用程序不应依赖此类行为

在我看来,您正在遵循“实体被修改并随后被删除”的场景。在您的情况下将PersistenceContext 分离时从PersistenceContext 中删除了含义,在这种情况下,行为是不可预测的。 经过一些测试后,我确认在这种情况下不会调用侦听器方法。

我找不到任何可以以任何方式强制执行此行为的其他配置。 希望对您有所帮助。

【讨论】:

  • 不是在我的电脑前测试,而是分离、更改和合并都在同一个事务中。 (不记得了,但我认为merge() 是通过TransactionAttribute.REQUIRES_NEW 的方法调用的,这有关系吗?)
  • 分离是在任何改变之前。
  • 就像我说的,这将是有益的,其他用户也可以看到交易代码,尤其是发生新交易的情况并不常见
  • 答案很好。但我将其归结为一个完全不同的问题。还是谢谢。
【解决方案2】:

我遇到了同样的问题,将方法从私有更改为公共,它工作。

接口在运行时以公共方法为目标。

【讨论】:

    猜你喜欢
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-29
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    相关资源
    最近更新 更多