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

如何在Hibernate 6与Spring Boot 3中正确配置数据库级默认值

为SQL Server字段设置Hibernate默认值的正确方式

问题场景

在Hibernate 6之前,Hibernate不会触发修改数据库或字段长度的ALTER语句,但通过columnDefinition设置default关键字时,生成的ALTER语句在SQL Server中语法无效。

代码片段

public abstract class AbstractAuditingEntity implements Serializable {

    private static final long serialVersionUID = 8559071964734620120L;

    @CreatedBy
    @JsonIgnore
    @Column(name = "CREATED_BY", updatable = false)
    private Integer createdBy;

    @CreatedDate
    @JsonIgnore
    @Column(name = "CREATED_DATE", columnDefinition="datetime default GETDATE()", updatable = false)
    private Instant createdDate = Instant.now();

    @LastModifiedBy
    @JsonIgnore
    @Column(name = "LAST_MODIFIED_BY")
    private Integer lastModifiedBy;

    @LastModifiedDate
    @JsonIgnore
    @Column(name = "LAST_MODIFIED_DATE")
    private Instant lastModifiedDate = Instant.now();
}

Hibernate生成的错误DDL语句

alter table TABLE_NAME alter column CREATED_DATE datetime default GETDATE()

抛出的异常

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table TABLE_NAME alter column CREATED_DATE datetime default GETDATE()" via JDBC [Incorrect syntax near the keyword 'default'.]

SQL Server中默认值属于约束,需要使用ADD CONSTRAINT语法,但可以通过Hibernate的特定方式实现正确的默认值配置。


正确实现方式

方法1:使用Hibernate扩展注解@ColumnDefault

Hibernate提供了org.hibernate.annotations.ColumnDefault注解,专门用于配置数据库字段的默认值,它会根据数据库方言自动生成符合语法的DDL语句,避免手动写columnDefinition带来的语法问题。

修改后的代码示例:

import org.hibernate.annotations.ColumnDefault;

public abstract class AbstractAuditingEntity implements Serializable {

    private static final long serialVersionUID = 8559071964734620120L;

    @CreatedBy
    @JsonIgnore
    @Column(name = "CREATED_BY", updatable = false)
    private Integer createdBy;

    @CreatedDate
    @JsonIgnore
    @Column(name = "CREATED_DATE", updatable = false)
    @ColumnDefault("GETDATE()")
    private Instant createdDate = Instant.now();

    @LastModifiedBy
    @JsonIgnore
    @Column(name = "LAST_MODIFIED_BY")
    private Integer lastModifiedBy;

    @LastModifiedDate
    @JsonIgnore
    @Column(name = "LAST_MODIFIED_DATE")
    @ColumnDefault("GETDATE()")
    private Instant lastModifiedDate = Instant.now();
}

方法2:自定义columnDefinition(需遵循SQL Server约束语法)

如果需要同时配置字段的其他属性,可以手动在columnDefinition中指定完整的约束定义,但这种方式在生成ALTER语句时可能存在兼容性问题,仅推荐在创建表时使用:

@Column(name = "CREATED_DATE", columnDefinition="datetime CONSTRAINT DF_CREATED_DATE DEFAULT GETDATE()", updatable = false)

额外注意事项

  • 实体类中= Instant.now()是Java对象初始化时的默认值,和数据库层面的默认值相互独立。如果希望数据库自动使用默认值,可在类级别添加@DynamicInsert注解,这样当字段为null时,Hibernate生成的INSERT语句不会包含该字段,数据库会自动应用默认值。
  • 确保Hibernate配置了正确的SQL Server方言,比如org.hibernate.dialect.SQLServerDialect或对应版本的方言,以保证生成的DDL适配SQL Server语法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:27:45