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

向H2内存库插入数据时触发ID主键约束冲突问题求助

H2内存数据库主键约束冲突问题分析

是的,"PRIMARY KEY ON MY_TABLE(ID)"明确表示这是主键ID的约束冲突,错误代码23505是SQL标准中定义的唯一约束/主键冲突错误码,和表中其他唯一约束无关。

问题根源

你使用的BIGSERIAL是H2的自增主键类型,它依赖内置序列自动生成ID。当你手动指定ID值插入数据时(比如最小示例中的INSERT INTO MY_TABLE(ID, VAL) VALUES (2, 99);),H2不会自动更新序列的计数器。后续用default插入时,序列仍会从初始值(通常为1)开始生成,当生成的ID与之前手动插入的ID重复时,就会触发主键冲突。

测试场景的触发原因

你的测试套件中应该存在某个测试手动指定了ID插入数据,后续测试未重置数据库状态(比如未重建表、未重置序列),导致自增生成的ID与已存在的ID重复,即使测试串行执行也会出现该问题。

最小复现示例

-- 创建表
CREATE TABLE MY_TABLE (
  id BIGSERIAL PRIMARY KEY,
  val BIGINT NOT NULL
);

-- 手动指定ID插入
INSERT INTO MY_TABLE(ID, VAL) VALUES (2, 99);

-- 使用自增插入,第三次插入时会触发主键冲突
INSERT INTO MY_TABLE(ID, VAL) VALUES (default, 99);
INSERT INTO MY_TABLE(ID, VAL) VALUES (default, 99);
INSERT INTO MY_TABLE(ID, VAL) VALUES (default, 99);

解决方法

  • 统一使用default让数据库自动生成主键ID,避免手动指定ID值。
  • 若必须手动插入ID,插入后需手动更新序列,确保后续自增ID不重复:
ALTER SEQUENCE MY_TABLE_ID_SEQ RESTART WITH (SELECT MAX(ID) + 1 FROM MY_TABLE);
  • 测试场景下,每个测试用例执行前重置数据库状态(如重建表、清空表并重置序列),避免测试间状态污染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 08:43:27