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

升级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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:06:18