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
相关产品推荐
相关产品推荐

