Java JPA/Hibernate:如何在实体更新时自动更新字段

Java JPA/Hibernate:如何在实体更新时自动更新字段,java,hibernate,jpa,Java,Hibernate,Jpa,我使用Camel和JPA将实体持久化到Postgres数据库。在每个实体中,我都有一个名为“history”的字段,其中包含给定实体的所有旧值。我正在寻找一种在每次更新操作之前自动填充此字段的方法。 在网上冲浪时,我发现了JPA拦截器,但我看到它们被用于审计/记录目的。我错了吗? 最好的方法是什么?JPA/Hibernate拦截器(取决于您使用的版本)是一种方法。审核/日志记录与您希望执行的操作类似,即在更新实体本身(任何属性)时自动更新某些列/属性。请注意,手动更新查询会绕过这些拦截器,因此应

我使用Camel和JPA将实体持久化到Postgres数据库。在每个实体中,我都有一个名为“history”的字段,其中包含给定实体的所有旧值。我正在寻找一种在每次更新操作之前自动填充此字段的方法。 在网上冲浪时,我发现了JPA拦截器,但我看到它们被用于审计/记录目的。我错了吗?
最好的方法是什么?

JPA/Hibernate拦截器(取决于您使用的版本)是一种方法。审核/日志记录与您希望执行的操作类似,即在更新实体本身(任何属性)时自动更新某些列/属性。请注意,手动更新查询会绕过这些拦截器,因此应该避免使用这些拦截器


但是,如何使用这些拦截器取决于如何实现历史记录功能。如果您是通过生成一些字符串/字节表示并将其存储在列中来实现的,那么它应该可以工作。如果您计划创建另一个实体等,则可能必须在拦截器中收集更改/旧值,并在成功提交后存储收集的值。好的,当拦截器被调用时,创建一个新的实体是不可能的(至少不容易)。

您可以使用
@EntityListeners
并向其提供您的实体侦听器类,并且您还可以随时重用它

@Entity
@Table(name = "entities")    
public class Entity {
  ...

  private Date created;
  private Date updated;

  @PrePersist
  protected void onCreate() {
    created = new Date();
  }

  @PreUpdate
  protected void onUpdate() {
    updated = new Date();
  }
}
在实体侦听器类中,可以为回调方法提供
@PrePersit、@postersist、@PreUpdate、@postpdate、@PreDelete、@PostDelete
注释。这些方法将自动为各自的操作调用


您可以阅读更多详细信息。

您计划如何将更改存储在一列中?@Funtik这是一个json字段,默认情况下由Postgre处理。我认为您也可以使用db触发器。我更希望在您已经检查的ApplicationID中拥有更多控制权?这是在Hibernate中创建历史记录的常用方法。感谢您的回复。对于“手动更新查询”,您是指直接在数据库上执行的查询(不使用应用程序)?在这种情况下,我可以摆脱它。@dylaniato我指的是在实体管理器上直接调用的任何查询(JPQL/HQL或SQL)。为了让拦截器工作,您必须让Hibernate找出更改并触发查询,至少这是我们目前从测试/实现中学到的。