Spring Boot启动运行Liquibase脚本生成测试数据主键重复,如何每次新增行?
解决方案
问题根因
报错的核心原因是你在INSERT语句中硬编码生成了固定范围的主键ID值(1~355),而你配置了主键为GenerationType.IDENTITY类型,由数据库自增维护主键唯一性,脚本重复执行时相同ID已经存在,就会触发主键唯一约束冲突。
最优修复方案
INSERT语句不要手动指定ID字段,完全交给数据库的自增IDENTITY逻辑生成主键,每次执行都会自动追加355条全新数据,不会出现主键重复问题,修改后的SQL如下:
INSERT INTO tasks (business_name, created_at, meta_title, status, title, task_type, updated_at) SELECT 'Business name ' || seq, NOW() + (random() * INTERVAL '90 days') + INTERVAL '30 days', left(md5(random()::text), 10), left(md5(random()::text), 10), left(md5(random()::text), 10), left(md5(random()::text), 10), NOW() + (random() * INTERVAL '90 days') + INTERVAL '30 days' FROM generate_series(1, 355) AS seq;
这个方案完全适配你现有的Hibernate主键配置,后续Hibernate插入数据时也不会出现序列不同步的问题。
备用方案(需手动指定ID的场景)
如果你有特殊需求必须手动生成ID值,可以基于表中现有最大ID作为生成起点,同时执行完插入后同步自增序列的最新值,避免后续Hibernate插入数据冲突,SQL如下:
-- 基于当前最大ID生成新的主键值 INSERT INTO tasks (id, business_name, created_at, meta_title, status, title, task_type, updated_at) SELECT (SELECT COALESCE(MAX(id), 0) FROM tasks) + seq AS id, 'Business name ' || seq, NOW() + (random() * INTERVAL '90 days') + INTERVAL '30 days', left(md5(random()::text), 10), left(md5(random()::text), 10), left(md5(random()::text), 10), left(md5(random()::text), 10), NOW() + (random() * INTERVAL '90 days') + INTERVAL '30 days' FROM generate_series(1, 355) AS seq; -- 同步自增序列到最新的最大值,避免Hibernate插入时主键冲突 SELECT setval(pg_get_serial_sequence('tasks', 'id'), (SELECT MAX(id) FROM tasks));
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

