You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot更新时save()未返回数据库生成的timestamp列问题

解决Spring Boot JPA更新实体时数据库生成的timestamp字段返回null问题

问题根源

  1. @CreationTimestamp(source = SourceType.DB) 仅在插入新实体时触发数据库生成时间戳并同步到实体对象,更新操作时Hibernate不会主动从数据库读取该字段的已有值。
  2. 当前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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 15:14:56