【问题标题】:Spring JPA Hibernate Auto Populate Audit Fields (Create ID / Timestamp etc)Spring JPA Hibernate 自动填充审计字段(创建 ID/时间戳等)
【发布时间】:2019-08-28 23:30:07
【问题描述】:

我有一个要审计的实体类:

@Data    // Lombok for getters/setters
@Entity
public class EventEntity {
  @Id
  private Long id;
  @CreatedBy
  private String createdId;
  private LocalDateTime creationTimestamp;  // @CreatedDate or @CreationTimestamp
  @LastModifiedBy
  private String modifiedId;
  private LocalDateTime lastModifiedTimestamp; // @LastModifiedDate or @UpdateTimestamp
  // other fields
}

我有一个JpaRepository 用于数据库操作:

public interface EventRepository extends JpaRepository<EventEntity, Long> {
  // Empty
}

有这些注释,我不确定我应该使用哪个日期注释:

org.springframework.data.annotation.CreatedBy
org.springframework.data.annotation.CreatedDate
org.hibernate.annotations.CreationTimestamp

org.springframework.data.annotation.LastModifiedBy
org.springframework.data.annotation.LastModifiedDate
org.hibernate.annotations.UpdateTimestamp

对于 @CreatedBy / @LastModifiedBy 字段,我根据仅返回常量的文档实现了 org.springframework.data.domain.AuditorAware

@Component("auditor")
public class CustomAuditorAware implements AuditorAware<String> {

@Override
  public Optional<String> getCurrentAuditor() {
     return Optional.of("ID");
  }
}

我已经启用了 JPA 审计:

@Configuration
@EnableJpaAuditing("auditor")
public class AppConfig {
}

这是我尝试坚持到数据库的方式:

EventEntity eventEntity = eventRepository.findById("ID") // returns Optional
    .orElse(new EventEntity());
eventEntity.setSomeField("New Value");
eventRepository.save(eventEntity);

(如果我在下面的错误,请在休眠实体状态上纠正我)

情况1:EventEntity是新的

调用了无参数构造函数,现在eventEntity 处于transient 状态。 save() 方法执行 select 查询,然后执行 update 查询,这将出错并显示以下消息:

java.sql.BatchUpdateException: Cannot insert the value NULL into column 'CREATED_ID'

情况2:EventEntity已经存在

eventEntity 现在处于分离状态。审核字段已填充。 save() 方法执行 update 查询,但没有更改任何审计字段。

理想的解决方案

我并不关心任何现有的数据字段,我只想更新它是否已经存在。所以理想情况下我不会调用findById() 方法。我将在 transient 状态下创建一个EventEntity,它将保留createdIdcreationTimestamp 数据。所以几乎就像上面一样:

EventEntity eventEntity = new EventEntity();
eventEntity.setSomeField("New Value");
eventRepository.save(eventEntity);

我的问题

所有审计字段都没有按我的预期工作。如何让它工作?

我应该使用哪些审计日期注释?来自 Spring JPA 还是来自 hibernate 的那个?我试过两套都没有运气。各有什么区别?

版本

  • Spring Boot 2.1
  • 休眠 5.3.10.final

【问题讨论】:

    标签: java spring hibernate spring-boot jpa


    【解决方案1】:

    只需在实体类中添加如下注解

    @EntityListeners(AuditingEntityListener.class)
    

    【讨论】:

      猜你喜欢
      • 2017-11-03
      • 2011-09-09
      • 1970-01-01
      • 1970-01-01
      • 2021-09-15
      • 2020-01-20
      • 1970-01-01
      • 2018-02-04
      • 1970-01-01
      相关资源
      最近更新 更多