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

标签 java spring hibernate spring-boot jpa

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

@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);

(如果我在下面有误,请纠正我的 hibernate 实体状态)

情况一:EventEntity是新的

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

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

情况二:EventEntity已经存在

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

理想的解决方案

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

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

我的问题

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

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

版本:

  • Spring 启动 2.1
  • hibernate 5.3.10.final

最佳答案

在实体类中添加如下注解即可

@EntityListeners(AuditingEntityListener.class)

关于java - Spring JPA Hibernate 自动填充审计字段(创建 ID/时间戳等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57701187/

相关文章:

java - 如何将条件转换为oracle sql查询

mysql - Spring数据JPA、Hibernate、MySQL5.7.13 : cannot find entity with chinese character

java - 当文件存在且无法删除时如何测试方法异常?

java - 我如何断言两个具有 Javabean 值的 HashMap 相等?

java - MongoDB聚合Spring/Java(带有数组、分组和匹配的项目)

spring - 从docker run命令运行时,来自Docker的图像无法按预期工作

java - Hibernate返回空对象

java - 如何从 Java 中的对象 ArrayList 获取 ArrayList 值?

java - Robot 的 getPixelColor(int x, int y) 方法如何工作?

java - Bitronix + Spring + Hibernate + Mysql 启动时卡住