Spring Data JDBC中@CreatedDate更新时被设为null的问题
问题解决:Spring Data JDBC @CreatedDate更新时被设为null
这是Spring Data JDBC的预期行为,它的审计逻辑和JPA不同:@CreatedDate仅在实体首次插入时自动赋值,更新操作时不会自动保留原有字段值,也不会跳过该字段的更新——如果实体中的createdAt为null,就会把null写入数据库。
可行解决方案(除你提到的两种外)
1. 使用@ReadOnlyProperty注解
Spring Data JDBC提供的@ReadOnlyProperty可以标记字段为只读,更新时会忽略该字段,不会将null值写入数据库。只需在createdAt字段上添加该注解:
@Table("my_entity") public class MyEntity { @Id private final Long id; @Column("created_at") @CreatedDate @ReadOnlyProperty // 新增只读标记 private Instant createdAt; public MyEntity (Long id) { this.id = id; } public Long getId() { return id; } public Instant getCreatedAt() { return createdAt; } public void setCreatedAt(Instant createdAt) { this.createdAt = createdAt; } }
2. 自定义更新回调
通过实现BeforeConvertCallback,在更新前自动填充原有createdAt值,适合需要更灵活审计逻辑的场景:
@Component public class MyEntityAuditCallback implements BeforeConvertCallback<MyEntity> { private final MyRepository repository; public MyEntityAuditCallback(MyRepository repository) { this.repository = repository; } @Override public MyEntity onBeforeConvert(MyEntity entity) { // 若实体已有ID(更新操作),从数据库获取原有createdAt值 if (entity.getId() != null) { repository.findById(entity.getId()) .ifPresent(existingEntity -> entity.setCreatedAt(existingEntity.getCreatedAt())); } return entity; } }
为什么之前的尝试无效
- 移除getter/setter:Spring Data JDBC需要访问字段进行读写操作,且审计逻辑与getter/setter无直接关联,因此该操作无效。
- JPA的
updatable=false:Spring Data JDBC的@Column注解不支持该属性,它的字段更新控制逻辑与JPA完全独立,因此此方案不适用。
关于配置
你的@EnableJdbcAuditing配置是正确的,它已经开启了JDBC审计功能,但该功能默认仅在插入时处理@CreatedDate,更新时不会自动维护该字段,因此需要通过上述方案补充控制。
内容的提问来源于stack exchange,提问作者Nanella
相关产品推荐
相关产品推荐

