Spring Boot更新时save()未返回数据库生成的timestamp列问题
解决Spring Boot JPA更新实体时数据库生成的timestamp字段返回null问题
问题根源
@CreationTimestamp(source = SourceType.DB)仅在插入新实体时触发数据库生成时间戳并同步到实体对象,更新操作时Hibernate不会主动从数据库读取该字段的已有值。- 当前update方法直接将请求体中的User对象(dateCreated为null)复制ID后执行save,JPA执行更新后返回的实体基于传入的对象构建,不会自动刷新未修改的字段值。
可行解决方案
方案1:更新后主动查询数据库
修改服务层的update方法,完成更新后重新查询实体,确保获取包含完整字段的最新数据:
fun update(id: Int, user: User): User { userRepository.save(user.copy(id = id)) return userRepository.findByIdOrNull(id) ?: error("用户不存在") }
方案2:通过注解配置字段自动刷新
替换原有的@CreationTimestamp,使用@Generated注解让Hibernate在更新后同步该字段值,同时配置字段不可插入和更新:
@Entity(name = "users") @Table(name = "users") data class User( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Int?, val name: String, @Column(name = "date_created", updatable = false, insertable = false) @Generated(GenerationTime.ALWAYS) val dateCreated: OffsetDateTime?, )
注意:需确保Postgres数据库中
date_created列已设置默认值DEFAULT CURRENT_TIMESTAMP,保证插入时自动生成时间戳。
代码优化建议
当前PUT请求的更新逻辑存在风险,直接用请求体覆盖实体可能导致意外字段丢失。建议先查询现有实体,仅更新需要修改的字段:
fun update(id: Int, user: User): User { val existingUser = userRepository.findByIdOrNull(id) ?: error("用户不存在") val updatedUser = existingUser.copy(name = user.name) return userRepository.save(updatedUser) }
这种方式基于已有实体修改,dateCreated字段本身已有值,save后返回的实体自然保留该字段数据,无需额外查询。
内容的提问来源于stack exchange,提问作者FinnCoal
相关产品推荐
相关产品推荐

