Java @PreUpdate 不适用于 Spring Data JPA

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19842541/
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-12 20:37:51  来源:igfitidea点击:

@PreUpdate does not work with Spring Data JPA

javaspringjpaspring-data-jpa

提问by fracz

I have an entity:

我有一个实体:

@Entity
@EntityListeners(MyEntityListener.class)
class MyEntity{ ... }

And the listener:

和听众:

class MyEntityListener{
    @PrePersist
    @PreUpdate
    public void doSomething(Object entity){ ... }
}

I'm using the Spring Data generated DAO for this entity (1.4.1) and EclipseLink. The code behavior is as follows:

我正在为此实体 (1.4.1) 和 EclipseLink 使用 Spring Data 生成的 DAO。代码行为如下:

MyEntity entity = new Entity();
entity = dao.save(entity); // the doSomething() is called here
// change something it the entity and save it again
dao.save(entity); // the doSomething() is NOT called here, checked with breakpoint

The problem has already been described by someone in 2009, however, they did not came up with any solution. I wonder if anyone has and idea how to solve it?

这个问题在2009年已经有人描述过了,但是他们没有想出任何解决方案。我想知道是否有人有并知道如何解决它?

采纳答案by Andrei I

As you said, the callback method is calledthe second time, if the entity is detached or fetched again from DB.

如您所说,如果实体从数据库中分离或再次获取,则第二次调用回调方法。

I cannot explain it exactly, but can think of the scenario described here, when no dirty fields are identified before the second save()call and thus the @PreUpdate callback not called. Or it may be simply a bug within your version of EclipseLink.

我无法准确解释它,但可以想到这里描述的场景,当在第二次save()调用之前没有识别出脏字段,因此没有调用 @PreUpdate 回调。或者它可能只是您的 EclipseLink 版本中的一个错误。



UPDATE

更新

In the JPA 2.0 specification I found the following, which is exactly your behaviour (3.5.2 Semantics of the Life Cycle Callback Methods for Entities):

在 JPA 2.0 规范中,我发现了以下内容,这正是您的行为(3.5.2 实体生命周期回调方法的语义):

Note that it is implementation-dependent as to whether PreUpdate and PostUpdate call- backs occur when an entity is persisted and subsequently modified in a single transaction or when an entity is modified and subsequently removed within a single transaction. Portable applications should not rely on such behavior.

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

回答by Terry Zhao

what is your transactional setting around your two different save()?

您围绕两个不同的 save() 的交易设置是什么?

I think there would be some differnce between save()/update()/merge()/persist(), for the different status of an entity(transient, persistent, detached), the operations is not the same as you thought and your annotation @PrePersist and @PreUpdate did not take effect.

我认为 save()/update()/merge()/persist() 之间会有一些区别,对于实体的不同状态(transient、persistent、detached),操作和你想的不一样,你的注解@PrePersist 和@PreUpdate 没有生效。