@PreUpdate不适用于Spring Data JPA

2022-09-04 21:25:30

我有一个实体:

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

听众:

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

我正在为这个实体(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

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


答案 1

如您所说,如果实体被分离或再次从 DB 中提取,则第二次调用回调方法。

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


更新

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

请注意,对于在单个事务中持久保存并随后修改实体时,还是在单个事务中修改并随后删除实体时,是发生 PreUpdate 和 PostUpdate 回调,这取决于实现。可移植应用程序不应依赖于此类行为。


答案 2

围绕两个不同的保存()的事务设置是什么?

我认为save()/update()/merge()/persist()之间会有一些差异,对于实体的不同状态(暂时的,持久的,分离的),操作与您想象的不同,您的注释@PrePersist,@PreUpdate没有生效。


推荐