Liquibase结合MySQL自动生成UUID主键的报错问题咨询
问题解决:Liquibase插入数据时自动生成UUID主键报错
错误原因分析
从报错信息的SQL语句可明确,建表语句中id列的约束顺序违反MySQL语法要求:
id VARCHAR(36) DEFAULT uuid() NOT NULL
MySQL规定非空约束(NOT NULL)必须放在默认值(DEFAULT)声明之前;同时MySQL 5.7及更早版本不支持将函数作为字符串类型列的默认值,这两点是触发语法错误的核心原因。
解决方案
方案1:适配MySQL 8.0+版本(支持函数作为默认值)
修改建表的changeSet,调整约束顺序并规范defaultValueComputed的用法:
<property name="u_id" value="UUID()" dbms="mysql"/> <changeSet id="1" author="xyz"> <createTable tableName="persons"> <column name="id" type="varchar(36)" nullable="false" defaultValueComputed="${u_id}"> <constraints primaryKey="true"/> </column> <column name="name" type="varchar(50)"> <constraints nullable="false"/> </column> <column name="surname" type="varchar(50)"> <constraints nullable="false"/> </column> <column name="email" type="varchar(50)"> <constraints nullable="false" unique="true"/> </column> </createTable> </changeSet> <changeSet id="2" author="xyz"> <insert tableName="persons"> <column name="name" value="name value"/> <column name="surname" value="surname value"/> <column name="email" value="email value"/> </insert> </changeSet>
核心调整:
- 将
nullable="false"直接定义在<column>标签上,确保生成的SQL顺序为NOT NULL DEFAULT UUID() defaultValueComputed用于指定数据库端计算的默认值,Liquibase会自动适配MySQL语法生成正确语句
方案2:适配MySQL 5.7及更早版本(不支持函数作为字符串默认值)
旧版本MySQL无法直接用函数作为字符串列默认值,需通过触发器实现UUID自动生成:
- 创建不含默认值的主键列:
<changeSet id="1" author="xyz"> <createTable tableName="persons"> <column name="id" type="varchar(36)"> <constraints primaryKey="true" nullable="false"/> </column> <column name="name" type="varchar(50)"> <constraints nullable="false"/> </column> <column name="surname" type="varchar(50)"> <constraints nullable="false"/> </column> <column name="email" type="varchar(50)"> <constraints nullable="false" unique="true"/> </column> </createTable> </changeSet>
- 创建插入前自动赋值UUID的触发器:
<changeSet id="1.1" author="xyz" dbms="mysql"> <sql> CREATE TRIGGER trg_persons_generate_uuid BEFORE INSERT ON persons FOR EACH ROW SET NEW.id = UUID(); </sql> <rollback>DROP TRIGGER trg_persons_generate_uuid;</rollback> </changeSet>
- 插入数据的changeSet保持不变:
<changeSet id="2" author="xyz"> <insert tableName="persons"> <column name="name" value="name value"/> <column name="surname" value="surname value"/> <column name="email" value="email value"/> </insert> </changeSet>
核心说明:
- 触发器会在每次插入操作前自动为主键字段生成UUID
- 添加
rollback语句保证迁移回滚时能清理触发器
验证方式
执行Liquibase迁移后:
- MySQL 8.0+版本可查看表结构,确认
id列定义为VARCHAR(36) NOT NULL DEFAULT UUID() - 旧版本可检查触发器是否存在,插入数据后验证
id列是否自动填充UUID值
内容的提问来源于stack exchange,提问作者Lulex97
相关产品推荐
相关产品推荐

