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

JPA如何在Oracle中设置CURRENT_TIMESTAMP默认值并格式化日期

你之前的配置出现小数的核心原因是Oracle默认的CURRENT_TIMESTAMP返回带6位小数秒的TIMESTAMP WITH TIME ZONE类型,同时JPA实体映射的字段没有限制精度,导致小数秒被存入数据库。以下是可直接落地的解决方案:

方案1:数据库层面控制(推荐,和MySQL逻辑一致,默认值由数据库维护)

直接通过columnDefinition显式指定Oracle兼容的字段类型和默认值,数据库层面直接截断小数秒,无需代码逻辑处理:

@CreationTimestamp
@Column(
    name = "created_date",
    insertable = false,
    updatable = false,
    // Oracle的DATE类型天然精确到秒,无小数秒,SYSDATE返回当前系统时间到秒
    columnDefinition = "DATE DEFAULT SYSDATE"
)
protected LocalDateTime createdDate;

如果偏好使用TIMESTAMP类型,可指定精度为0:

columnDefinition = "TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP"

注意:如果你的表已经创建完成,需要先执行DDL修改现有字段属性,示例:

ALTER TABLE 你的表名 MODIFY created_date DATE DEFAULT SYSDATE;

方案2:JPA层面控制(适配多数据库场景)

如果需要兼容MySQL、Oracle多数据源,不想写数据库特定的columnDefinition,可以通过@PrePersist钩子在实体插入前手动截断时间到秒:

import java.time.temporal.ChronoUnit;
import javax.persistence.PrePersist;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.ColumnDefault;

@CreationTimestamp
@ColumnDefault("CURRENT_TIMESTAMP")
@Column(name = "created_date", updatable = false)
protected LocalDateTime createdDate;

@PrePersist
protected void onCreate() {
    // 手动截断纳秒部分,仅保留到秒
    if (createdDate == null) {
        createdDate = LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
    } else {
        createdDate = createdDate.truncatedTo(ChronoUnit.SECONDS);
    }
}

这个方案不需要修改数据库现有字段,实体层面就保证存入的时间没有小数秒。

内容的提问来源于stack exchange,提问作者iwritecomeinmymind

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:36:03