Spring JPA Hibernate自动填充审计字段(创建ID / 时间戳等)

3

我有一个实体类需要进行审计:

@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处于瞬态状态。执行save()方法将执行select查询,然后是一个update查询,这将导致以下错误信息:

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

情境二:EventEntity已经存在

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

理想解决方案

我并不关心任何现有数据字段,只要已经存在就进行更新。因此,理想情况下,我不需要调用findById()方法。我将创建一个处于瞬态状态的EventEntity,它将保留createdIdcreationTimestamp数据。就像上面说的一样:

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

我的问题

我期望的审计字段都没有按照预期工作。我该如何让它正常工作?

我应该使用哪个审计日期注释?Spring JPA 还是 Hibernate?我已经尝试了两种设置但都没有成功。每种方法有什么不同呢?

版本信息:

  • Spring Boot 2.1
  • Hibernate 5.3.10.final
1个回答

2
只需在实体类中添加以下注释即可:

```@OriginalAnswer```
@EntityListeners(AuditingEntityListener.class)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接