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

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自动生成:

  1. 创建不含默认值的主键列:
<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>
  1. 创建插入前自动赋值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>
  1. 插入数据的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:15:39