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

JPA/Hibernate操作Oracle:持久化实体时跳过自动生成ID列问题

Oracle 11g+Hibernate的IDENTITY主键保存问题解决方案

环境信息

  • Oracle数据库实际版本:11g(配置标注为19)
  • Hibernate版本:5.5.4
  • 使用方言:org.hibernate.dialect.Oracle12cDialect
  • JDBC驱动版本:12.2.0.1

问题场景与报错

需通过JPA/Hibernate保存带有自动生成ID列(PROT_ID)的实体,数据库表创建语句如下:

CREATE TABLE SOME_PROTOCOL(
  PROT_ID       NUMBER(18) GENERATED ALWAYS AS IDENTITY (START WITH 123 MAXVALUE 99999) NOT NULL,
  MORE_COLS     VARCHAR2(500 CHAR) NOT NULL);

手动插入时需跳过ID列,正确语句为:

insert into SOME_PROTOCOL (MORE_COLS) values ('Some Value'); 

对应的实体类代码:

@Entity
@Table(name = "SOME_PROTOCOL")
public class SomeProtocol {
  @Id 
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "PROT_ID", insertable = false)
  private Long id;
  // Getter, Setter, 其他字段
}

执行保存操作:

SomeProtocol s = new SomeProtocol();
s.setMoreCols("whatever");
hibernateSession.save(s);

出现报错:

ERROR: Invalid argument(s) in call
Hibernate: insert into APPL_PROTOCOL (PROT_ID, MORE_COLS) values (default, ?)

JPA并未跳过ID列,反而传入default值,尝试@Column(insertable=false)、GenerationType.AUTO均无法解决问题。

解决方案

将表的ID生成方式改为外部序列,即可让Hibernate正常保存实体。修改后的实体类ID字段代码如下:

@SequenceGenerator(name = "SEQ_APPL_PROT_GENERATOR", sequenceName = "SEQ_APPL_PROTOCOL_ID", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_APPL_PROT_GENERATOR")
@Column(name = "PROT_ID")
private Long id;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:25:15