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

Hibernate持久化EntityA实体时抛出异常,如何解决?

问题描述

实体EntityA的id定义如下:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence")
@SequenceGenerator(name = "sequence", sequenceName = "sequence", allocationSize = 1)
private Long id;

持久化新条目时出现如下错误:

Hibernate: select next value for sequence
Hibernate: insert into dbo.entityA (field1, field2, id) values (?,?,?)
Caused by: java.sql.BatchUpdateException: Cannot insert explicit value for identity column in table 'entityA' when IDENTITY_INSERT is set to OFF.

表结构定义:

IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID('dbo.entityA') AND type = 'SO')
BEGIN
CREATE SEQUENCE sequence
    AS BIGINT
    START WITH 1
    INCREMENT BY 1
    MINVALUE 1
    NO MAXVALUE
    CACHE 1000;
END
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.entityA') AND type in (N'U'))
BEGIN
    CREATE TABLE dbo.entityA(
        id BIGINT NOT NULL CONSTRAINT PK_id PRIMARY KEY DEFAULT (NEXT VALUE FOR sequence),
        field1 varchar(20) not null,
        field2 varchar(20) not null
    );
END

持久化代码未手动设置id:

EntityA entityA = new EntityA();
entityA.setField1("test");
entityA.setField2("test");
entityARepository.save(entityA);
解决方案

错误根源是Hibernate使用SEQUENCE策略时,会主动获取序列值并在INSERT语句中显式传入id字段,但你的表通过DEFAULT约束让数据库自动生成id,SQL Server不允许这种显式插入操作。以下两种方案可解决问题:

方案一:修改实体类映射,禁止Hibernate插入id字段

在id字段的注解中添加@Column(insertable = false, updatable = false),让Hibernate在插入时不包含id字段,交由数据库通过DEFAULT约束生成值:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence")
@SequenceGenerator(name = "sequence", sequenceName = "sequence", allocationSize = 1)
@Column(insertable = false, updatable = false)
private Long id;

方案二:修改表结构为IDENTITY自增列

将表的id字段改为SQL Server的IDENTITY自增列,同时调整实体类的生成策略适配:

修改表结构SQL:

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.entityA') AND type in (N'U'))
BEGIN
    CREATE TABLE dbo.entityA(
        id BIGINT NOT NULL IDENTITY(1,1) CONSTRAINT PK_id PRIMARY KEY,
        field1 varchar(20) not null,
        field2 varchar(20) not null
    );
END

修改实体类id注解:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 13:35:06