Java Hibernate无法自动为MySQL填充Timestamp值问题排查
核心问题分析
你的timestamp字段为null主要有三个原因:
注解混用错误
@LastModifiedBy是Spring Data JPA的审计注解,作用是记录最后修改该数据的用户/操作者,类型应为String或关联的User实体,完全不能用在LocalDateTime类型的时间字段上。这个错误注解会干扰Hibernate@CreationTimestamp的正常工作。ORM层面自动填充不覆盖原生SQL操作
@CreationTimestamp是Hibernate(ORM框架)提供的注解,只有通过Spring Data JPA的save()/saveAll()等方法插入数据时,Hibernate才会自动填充这个时间字段。你直接用MySQL Workbench执行INSERT语句,绕开了ORM的处理逻辑,自然不会自动生成时间。数据库字段未设置默认值
即使不用ORM,要让数据库在插入时自动填充时间,需要给timestamp字段设置数据库层面的默认值,否则原生SQL插入时不指定该字段,就会存为null。
具体修复步骤
1. 修正实体类的注解与冗余代码
删掉错误的@LastModifiedBy注解,保留Hibernate的@CreationTimestamp(如果需要自动更新修改时间,可以再加@UpdateTimestamp)。同时删掉手动编写的getTimestamp/setTimestamp方法,因为@Data注解已经会自动生成这些方法,重复定义可能导致冲突。
修正后的timestamp字段代码:
@Column(name = "timestamp") @CreationTimestamp // 插入时自动生成创建时间 @UpdateTimestamp // 可选:更新时自动刷新时间 private LocalDateTime timestamp;
完整修正后的实体类(简化冗余代码):
import jakarta.persistence.*; import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @Entity @NoArgsConstructor @Data public class TempTable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 注意变量名规范:小写开头(和数据库字段对应更友好) private Float temperatures; @Column(name = "timestamp") @CreationTimestamp @UpdateTimestamp private LocalDateTime timestamp; @Transient public String getFormattedTimestamp(){ if (timestamp != null) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 'hour' HH : 'minute' mm : 'seconds' ss.SSS"); return timestamp.format(formatter); } System.out.println("无法格式化日期时间"); return ""; } @OneToMany(mappedBy = "tempTable", cascade = CascadeType.ALL) private List<WarningTable> warningTables = new ArrayList<>(); public TempTable(Long id, Float temperatures, LocalDateTime timestamp){ this.id = id; this.temperatures = temperatures; this.timestamp = timestamp; } }
2. 给数据库字段设置默认值
执行以下SQL修改temp_table的timestamp字段,让数据库原生插入时也能自动填充时间:
ALTER TABLE temp_table MODIFY COLUMN timestamp DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
DEFAULT CURRENT_TIMESTAMP:插入时自动填充当前时间ON UPDATE CURRENT_TIMESTAMP:可选,更新数据时自动刷新时间(和@UpdateTimestamp对应)
3. 验证两种插入方式
- 用Spring Data JPA的
tempTableRepository.save()方法插入:Hibernate会自动填充timestamp - 用MySQL Workbench执行INSERT语句:数据库会用默认值填充
timestamp
额外注意点
如果想使用Spring Data JPA的审计功能(比如@CreatedDate、@LastModifiedDate),需要:
- 把
@CreationTimestamp换成@CreatedDate,@UpdateTimestamp换成@LastModifiedDate - 保留
@EntityListeners(AuditingEntityListener.class)注解 - 在Spring Boot启动类上添加
@EnableJpaAuditing注解
不过你的场景用Hibernate原生的@CreationTimestamp更直接,不需要额外配置启动类。
内容的提问来源于stack exchange,提问作者Marcus Peterson

