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

Spring Boot+Oracle 11g:JPA与触发器生成ID值不一致问题

解决JPA与Oracle触发器重复获取序列ID的问题

问题根源

当前代码中,JPA通过@GeneratedValue(strategy = GenerationType.SEQUENCE)主动调用序列BOOK_ENTRY_SEQ.nextval生成ID,而数据库插入前触发器BOOK_ENTRY_TRG又会再次调用nextval设置ID,导致两次取值,出现调试ID为61但数据库存储为62的情况。

解决方案

要让触发器单独负责ID生成,需修改实体类的ID字段配置,让JPA不再主动生成ID,转而依赖触发器,并在插入后同步数据库生成的ID。

修改BookEntry实体类的ID字段

将原ID字段的注解替换为以下配置:

@Id
@Column(name = "ID", updatable = false, insertable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

如果Oracle 11g环境下GenerationType.IDENTITY不生效,可改用Hibernate专属注解:

@Id
@Column(name = "ID", updatable = false, insertable = false)
@Generated(GenerationTime.INSERT)
private Long id;

配置说明

  • 移除序列生成注解:删除@SequenceGenerator和@GeneratedValue(strategy = GenerationType.SEQUENCE),避免JPA主动调用序列取值。
  • insertable = false:确保JPA生成INSERT语句时不包含ID字段,给触发器留出设置ID的空间。
  • 生成策略注解:@GeneratedValue(strategy = GenerationType.IDENTITY)或@Generated(GenerationTime.INSERT)用于告知JPA,ID由数据库生成,插入操作完成后需要从数据库同步最新的ID值到实体对象。

验证效果

修改后调用save方法时:

  1. JPA生成的INSERT语句不包含ID字段;
  2. 触发器自动调用BOOK_ENTRY_SEQ.nextval为ID赋值;
  3. 插入完成后,JPA将数据库生成的ID同步回实体对象;
  4. 调试时看到的ID与数据库存储的ID完全一致,不会再出现跳号情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:13:15