@PrePersist 运行时,@PreUpdate 是不是总是运行?

Posted

技术标签:

【中文标题】@PrePersist 运行时,@PreUpdate 是不是总是运行?【英文标题】:Does @PreUpdate always run when @PrePersist runs?@PrePersist 运行时,@PreUpdate 是否总是运行? 【发布时间】:2019-06-11 09:10:01 【问题描述】:

我有一个像下面这样的实体:

@Entity
public class Order 

  @Id
  private String orderId;

  @Temporal(TemporalType.TIMESTAMP)
  @Column(name = "created_at", nullable = false)
  private Date created;

  @Temporal(TemporalType.TIMESTAMP)
  @Column(name = "updated_at", nullable = false)
  private Date updated;
  @PrePersist
  protected void onCreate() 
    this.created = new Date();
    this.updated = this.created;
  

  @PreUpdate
  protected void onUpdate() 
    this.updated = new Date();
  

我必须找到在特定日期范围内创建或更新日期的所有订单。为此,我在我的存储库中定义了以下方法:

public interface OrderRepository extends PagingAndSortingRepository<Order, String>,
    QuerydslPredicateExecutor<Order> 
 public Page<Order> findByCreatedBetweenOrUpdatedBetween(Date startCreatedDate,
      Date endCreatedDate, Date startUpdatedDate, Date endUptedDate, Pageable pageRequest);

我的问题是,我可以只检查Updated_date 而不是像下面这样的创建日期和更新日期吗?

public Page<Order> findByUpdatedBetween(Date startUpdatedDate, Date endUptedDate, Pageable pageRequest);

我观察到updated_date 在插入与created_date 相同值的行时更新。如果我只检查 updated_date 提供的日期范围,我是否有可能错过任何记录。

【问题讨论】:

你不是在@PrePersistthis.updated = this.created;中设置更新日期 【参考方案1】:

不,@PreUpdate 回调方法并不总是在执行@PrePersist 回调方法时运行。 @PrePersist 在持久化操作(直接或级联)之前执行,@PreUpdate 在数据库更新之前执行。

在 JPA 2.1 规范(实体的生命周期回调方法的语义的 3.5.3 语义)中,这是用以下词语说明的:

PrePersist 和 PreRemove 回调方法被调用 相应 EntityManager 之前的实体持久化并删除 执行该实体的操作。 ... 预更新和 PostUpdate 回调发生在数据库更新之前和之后 分别对实体数据进行操作。

【讨论】:

以上是关于@PrePersist 运行时,@PreUpdate 是不是总是运行?的主要内容,如果未能解决你的问题,请参考以下文章

使用 SessionFactory 配置 Hibernate 4.3 以使用 @PrePersist

Symfony2:PrePersist/PreUpdate 生命周期事件未触发

hibernate/JPA 中的 @PreUpdate 和 @Prepersist(使用会话)

如何使用 jpa/spring-boot 正确应用类似 PrePersist 的逻辑

JPA/Spring/Hibernate/etc 中是不是有类似于 JPA 的 @PrePersist 允许更改相关实体的功能?

我可以在 Sonata Admin 控制器中使用 prePersist/preUpdate 来持久化多个对象吗?