H2数据库中正确填充ManyToMany关联表的方法求助
解决H2数据库ManyToMany关联表插入外键约束错误的问题
首先咱们来拆解下你遇到的问题根源:
你用了GenerationType.IDENTITY作为ID生成策略,这意味着H2会自动给sessions.session_id和speakers.speaker_id生成自增ID。但你的data.sql里插入主表数据时没指定ID值,插入中间表session_speakers却用了(1,40)这类固定ID——要么这些ID在主表里根本不存在,要么和数据库自动生成的ID不匹配,自然触发了外键约束错误。
下面给你两种实用的解决思路:
方法一:显式指定主表ID,保证与中间表ID完全匹配
这是最直接有效的方案,修改你的data.sql脚本,在插入sessions和speakers时明确写出ID字段的值,确保中间表引用的ID在对应主表中存在:
-- 插入sessions时指定session_id INSERT INTO sessions (session_id, session_name,session_length,session_description) VALUES (1,'Keynote - The Golden Age of Software',45,''), (2,'A Better Way to Access Data with Spring Data',60,''), (3,'A Deep Dive Into Spring IoC',60,''); -- 插入speakers时指定speaker_id INSERT INTO speakers (speaker_id, first_name,last_name,title,company,speaker_bio) VALUES (40,'Sergio','Becker','Senior Developer','MicroOcean Software','Test'), (4,'James','Lowrey','Solutions Architect','Fabrikam Industries','Test'); -- 插入中间表,此时session_id和speaker_id都能在主表找到对应记录 INSERT INTO session_speakers (session_id,speaker_id) VALUES (1,40), (2,4), (3,5);
方法二:调整自增序列起始值(适合不想手动指定ID的场景)
如果你希望保持自动生成ID的逻辑,可以先修改H2的自增序列起始值,让自动生成的ID和你中间表用到的ID匹配:
-- 重置sessions表的session_id自增起始值 ALTER TABLE sessions ALTER COLUMN session_id RESTART WITH 1; -- 重置speakers表的speaker_id自增起始值 ALTER TABLE speakers ALTER COLUMN speaker_id RESTART WITH 4; -- 插入主表数据(无需指定ID,数据库会按设置的起始值自增) INSERT INTO sessions (session_name,session_length,session_description) VALUES ('Keynote - The Golden Age of Software',45,''), ('A Better Way to Access Data with Spring Data',60,''), ('A Deep Dive Into Spring IoC',60,''); INSERT INTO speakers (first_name,last_name,title,company,speaker_bio) VALUES ('James','Lowrey','Solutions Architect','Fabrikam Industries','Test'), ('Sergio','Becker','Senior Developer','MicroOcean Software','Test'); -- 插入中间表,此时自动生成的ID会和你预期的一致 INSERT INTO session_speakers (session_id,speaker_id) VALUES (1,2), (2,1);
小贴士:这种方法需要你理清数据插入顺序和自增序列的对应关系,避免出现ID错位的情况。
额外注意点
- 你现有
data.sql的执行顺序是对的:先插主表,再插中间表,这个逻辑不用改。 - 确认
spring.jpa.hibernate.ddl-auto=create配置生效:它会在每次测试时重建表,避免旧数据干扰新的插入操作。
内容的提问来源于stack exchange,提问作者Rafał Popławski
相关产品推荐
相关产品推荐

