JpaRepository saveAndFlush返回Timestamp为null问题求助
解决JPA保存实体后无法获取数据库生成时间戳的问题
问题场景
现有如下JPA实体类:
@AllArgsConstructor @NoArgsConstructor @Setter @Getter @Entity @Table(name = "t_org") public class Organization { /** * id of the organization. */ @Id @GeneratedValue(generator = "UUID") @Column(name = "c_id", columnDefinition = "BINARY(16) DEFAULT (UUID_TO_BIN(UUID(), TRUE))") private UUID id; /** * legal name of the organization. */ @Column(name = "c_legal_name", nullable = false, unique = true) private String legalName; /** * alias name of the organization. */ @Column(name = "c_alias", nullable = false, unique = true) private String alias; /** * timestamp when the organization was created. */ @Column(name = "c_date", insertable = false, updatable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP", nullable = false) private Instant ts; }
调用saveAndFlush(orgObject).getTs()时返回null,但数据库中该字段已成功生成时间戳。使用@CreationTimestamp会生成JVM时间,不符合需求,需要获取数据库端生成的时间戳。
解决方案
方案1:使用@Generated注解让JPA自动刷新字段
修改ts字段的注解,添加@Generated指定字段生成时机,让JPA在插入后从数据库同步该值:
@Column(name = "c_date", insertable = false, updatable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP", nullable = false) @Generated(GenerationTime.INSERT) // 插入后从数据库读取值 private Instant ts;
- 如果需要在更新操作时也同步该字段(因为数据库定义了
ON UPDATE CURRENT_TIMESTAMP),可以将GenerationTime.INSERT改为GenerationTime.ALWAYS,这样插入和更新后都会自动刷新实体中的ts值。 - 注意:该注解是JPA实现(如Hibernate)的扩展特性,需确保使用的JPA提供者版本兼容。
方案2:保存后重新查询实体
如果不想修改实体注解,也可以在保存后通过主键重新查询实体,获取最新的数据库数据:
Organization savedOrg = organizationRepository.saveAndFlush(orgObject); // 重新查询获取包含数据库生成时间戳的实体 savedOrg = organizationRepository.findById(savedOrg.getId()).orElseThrow(() -> new RuntimeException("Organization not found")); Instant dbGeneratedTs = savedOrg.getTs();
这种方式效率略低,但无需修改实体类定义。
额外说明
- 确保
Instant类型与数据库TIMESTAMP字段正确映射,Hibernate 5.2及以上版本已支持Instant与SQL时间类型的自动转换。 - 若使用其他JPA实现,可查阅对应文档确认类似的"数据库生成字段同步"配置方式。
内容的提问来源于stack exchange,提问作者DUMBLEDHOR
相关产品推荐
相关产品推荐

