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

升级Spring Boot 2.7后出现JdbcSQL唯一索引/主键冲突异常

异常产生原因

该问题是Spring Boot 2.7版本依赖升级、默认配置调整带来的行为变化共同导致的:

  • Spring Boot 2.7默认将spring.jpa.defer-datasource-initialization配置的默认值改为true,data.sql脚本会在Hibernate完成表结构创建后执行,你写在data.sql里的初始化插入语句可以正常执行。
  • Spring Boot 2.7默认内置2.x版本的H2数据库,该版本修改了IDENTITY自增列的核心逻辑:手动指定ID插入数据时,不会自动更新自增列的内部计数器,计数器仍会从初始值1开始计数。
  • 你在初始化脚本中手动插入了id=1的测试数据,但H2的自增计数器没有同步推进,当测试方法调用save()插入新数据时,生成的插入语句使用default关键字取自增列的下一个值,拿到的ID仍然是1,和已存在的ID=1记录冲突,最终抛出主键重复异常。
修复方案

根据实际使用场景选择任意一种方案即可:

  • 方案1:手动重置自增序列(推荐)
    这是通用性最强的方案,在data.sql的插入语句最后追加SQL,插入完初始化数据后自动把自增计数器调整到当前最大ID+1的位置,无论初始化插入多少条数据都不会出现ID冲突:
    INSERT INTO Model(id, description) VALUES (1, 'Model 1 Description');
    -- 追加以下语句重置自增起始值
    ALTER TABLE Model ALTER COLUMN id RESTART WITH (SELECT MAX(id)+1 FROM Model);
    
  • 方案2:初始化数据不手动指定ID
    如果业务不需要固定初始化数据的ID值,可以去掉插入语句中的id字段,让H2通过自增逻辑自动生成ID,自增计数器会在插入时自动推进:
    INSERT INTO Model(description) VALUES ('Model 1 Description');
    
  • 方案3:降级H2版本(不推荐)
    如果需要完全兼容旧版本逻辑,可以在pom.xml/gradle配置中把H2依赖版本降级到1.4.x系列,但1.x版本的H2存在已知安全漏洞,非特殊情况不建议使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 00:51:24