升级H2数据库至2.1.212报约束未找到异常如何调整SQL
问题根因
H2 从1.4.200升级到2.1.212版本后,对SQL标准的校验逻辑更严格:外键引用的目标列,必须被目标表的主键约束或者UNIQUE列约束直接覆盖,单独通过CREATE UNIQUE INDEX语句创建的唯一索引,不会被外键约束识别为合法的引用目标,这就是抛出约束不存在异常的核心原因,和SQL执行顺序没有关系。
修复方法
直接把itineraries表上单独为id列创建的唯一索引,调整为表定义内的UNIQUE约束即可。H2会为UNIQUE约束自动创建对应的唯一索引,和你原来单独创建唯一索引的效果完全一致,同时能被外键正常识别引用。
调整后可在H2 2.x版本正常执行的SQL如下:
CREATE TABLE itineraries ( id SERIAL, itinerary_id VARCHAR(36) NOT NULL, user_id VARCHAR(36) NOT NULL, created_at TIMESTAMP, version INTEGER DEFAULT 1, update_timestamp BIGINT, CONSTRAINT itineraries_pkey PRIMARY KEY (itinerary_id, user_id), CONSTRAINT itineraries_user_id_fkey FOREIGN KEY (user_id) REFERENCES users (user_id), -- 直接在表定义中添加id列的唯一约束,替代后续单独创建的唯一索引 CONSTRAINT itineraries_id_key UNIQUE (id) ); -- 移除原SQL中单独执行的CREATE UNIQUE INDEX itineraries_id_key语句,UNIQUE约束会自动生成同名唯一索引 CREATE TABLE subscriptions ( subscription_id VARCHAR(36) PRIMARY KEY NOT NULL, type VARCHAR(10) NOT NULL, status VARCHAR(20), last_updated TIMESTAMP NOT NULL, itinerary_id VARCHAR(36) NOT NULL, itinerary_db_id BIGINT, CONSTRAINT subscriptions_it_itinerary_id_fkey FOREIGN KEY (itinerary_db_id) REFERENCES itineraries (id) );
补充说明
- 无特殊需求不建议保留单独创建唯一索引的写法,UNIQUE约束自动生成的索引已经能满足唯一性校验、查询性能优化的需求,单独额外建索引会产生冗余存储。
- 该校验规则属于H2 2.0版本官方公布的不兼容变更项,所有外键引用非主键、无UNIQUE约束列的场景,哪怕目标列上存在单独创建的唯一索引,都会触发同类报错。
内容的提问来源于stack exchange,提问作者MrAndre
相关产品推荐
相关产品推荐

