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

JPA如何正确映射SQL Server带NEWID()默认值的UNIQUEIDENTIFIER主键

问题根因

你遇到的两个问题本质原因分别是:

  1. 默认配置下Hibernate会将java.util.UUID序列化为二进制数组传入SQL Server,Java的UUID采用大端字节序,而SQL Server UNIQUEIDENTIFIER类型的前三个字段采用小端字节序,直接存二进制会导致字节序翻转,出现实体值和数据库存储值不一致的情况
  2. 原生GenerationType.IDENTITY策略Hibernate默认没有适配UUID类型的主键返回逻辑,所以会抛出类型不匹配的异常

方案1:Hibernate生成UUID,与数据库存储值完全一致

该方案不需要依赖数据库的NEWID()默认值,直接让Hibernate生成UUID并正确写入数据库,实体id值和数据库存储值100%匹配,是最常用的解决方案:

@Entity
@Table(name = "some_table")
public class MyEntity {

    @Id
    @Column(columnDefinition = "uniqueidentifier", nullable = false)
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
    // *核心配置*:指定Hibernate将UUID转为字符串和数据库交互,避免字节序翻转问题
    @Type(type = "org.hibernate.type.UUIDCharType")
    private UUID id;

    // 其他字段、getter、setter
}

直接调用repository.save(entity)即可,无需手动设置id,保存后返回的实体id和数据库存储值完全一致。


方案2:使用数据库侧NEWID()生成主键,插入后回写实体

如果必须由数据库生成主键,使用如下配置即可,插入后数据库生成的UUID会自动回写到实体对象:

@Entity
@Table(name = "some_table")
public class MyEntity {

    @Id
    @Column(columnDefinition = "uniqueidentifier", nullable = false, insertable = false, updatable = false)
    // 标注该字段值由数据库插入时生成,插入后Hibernate会自动回查回填
    @Generated(GenerationTime.INSERT)
    @Type(type = "org.hibernate.type.UUIDCharType")
    private UUID id;

    // 其他字段、getter、setter
}

注意事项:

  • 不需要添加@GeneratedValue注解,避免触发Hibernate的id生成逻辑
  • insertable = false表示插入SQL时不携带id字段,让数据库触发NEWID()默认值逻辑
  • 确保使用4.0及以上版本的mssql-jdbc驱动,支持返回生成的UNIQUEIDENTIFIER类型主键

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 04:48:03