JOOQ结合Liquibase生成代码遇H2 SQL语法错误求解决
问题分析与解决方案
报错原因
你遇到的问题是H2数据库老版本(如2.1.214)不支持标准SQL的PRIMARY KEY GENERATED ALWAYS AS IDENTITY语法顺序,H2要求IDENTITY声明必须放在数据类型之后、主键约束之前,或者使用它兼容的AUTO_INCREMENT关键字。
是否需要修改SQL迁移语句?
直接修改SQL适配H2是可行的临时方案,但更推荐用Liquibase数据库差异化配置或升级H2版本来保持迁移脚本的跨数据库兼容性,避免破坏生产环境的标准SQL语法。
具体解决方案
方案1:调整SQL语法顺序(适配H2)
将原表结构中的id字段声明调整为H2支持的格式:
CREATE TABLE links ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, link VARCHAR(200) NOT NULL, CONSTRAINT unique_link UNIQUE (link) );
或者用H2兼容的AUTO_INCREMENT(注意:此语法仅适用于H2/MySQL,不适用于PostgreSQL等标准SQL数据库):
CREATE TABLE links ( id BIGINT PRIMARY KEY AUTO_INCREMENT, link VARCHAR(200) NOT NULL, CONSTRAINT unique_link UNIQUE (link) );
方案2:用Liquibase差异化配置(推荐)
利用Liquibase的多数据库支持,针对不同数据库执行不同SQL,既保留生产库的标准语法,又适配H2:
<changeSet id="create-links-table" author="your-name"> <!-- 针对H2的适配SQL --> <sql dbms="h2"> CREATE TABLE links ( id BIGINT PRIMARY KEY AUTO_INCREMENT, link VARCHAR(200) NOT NULL, CONSTRAINT unique_link UNIQUE (link) ); </sql> <!-- 针对PostgreSQL/其他支持标准SQL的数据库 --> <sql dbms="postgresql,mysql"> CREATE TABLE links ( id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, link VARCHAR(200) NOT NULL, CONSTRAINT unique_link UNIQUE (link) ); </sql> </changeSet>
或者用Liquibase的XML语法生成表结构(自动适配不同数据库):
<changeSet id="create-links-table" author="your-name"> <createTable tableName="links"> <column name="id" type="BIGINT"> <constraints primaryKey="true"/> <autoIncrement/> </column> <column name="link" type="VARCHAR(200)"> <constraints nullable="false" unique="true"/> </column> </createTable> </changeSet>
方案3:升级H2版本
H2 2.2.x及以上版本已经支持标准SQL的GENERATED ALWAYS AS IDENTITY语法,直接升级项目中的H2依赖版本即可,无需修改任何SQL脚本。
内容的提问来源于stack exchange,提问作者Black Winst
相关产品推荐
相关产品推荐

