【问题标题】:Duplicate entry Exception while generating UUID in Liquibase changeset在 Liquibase 变更集中生成 UUID 时出现重复条目​​异常
【发布时间】:2016-03-31 09:20:31
【问题描述】:

我正在使用 Liquibase 变更集来更新 null 列的 customId 值。 sql是this answer的修改版。

问题是它似乎对所有行使用相同的 UUID。我的变更集如下所示:

<changeSet id="v3.0.3" author="msp" runAlways="false">
    <preConditions onFail="MARK_RAN">
        <not>
            <sqlCheck expectedResult="0">select count(*) from FOOBAR where customId is null</sqlCheck>
        </not>
    </preConditions>

    <sql>update FOOBAR set customId = concat('cu:', (select uuid())) where customId is null</sql>
</changeSet>

请注意,如果我在 MySQL 控制台中运行这个稍微修改过的查询版本(添加限制为 2),那么它可以工作:

update FOOBAR set customId = concat('cu:', (select uuid())) where customId is null limit 2

但如果我尝试使用 liquibase 运行相同的查询(包括限制),我会收到以下异常:

Caused by: liquibase.exception.MigrationFailedException: Migration failed for change set changelog/db.changelog-v3.0.3.xml::v3.0.3::msp:
     Reason: liquibase.exception.DatabaseException: Error executing SQL update FOOBAR set customId = concat('cu:', (select uuid())) where customId is null limit 2: Duplicate entry 'cu:cde325da-f71f-11e5-95f8-d15a50829a7d' for key 'customId'
    at liquibase.changelog.ChangeSet.execute(ChangeSet.java:554)
    at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:43)
    at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:70)
    at liquibase.Liquibase.update(Liquibase.java:195)
    at liquibase.Liquibase.update(Liquibase.java:174)
    at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:330)
    at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:287)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)
    ... 77 more
Caused by: liquibase.exception.DatabaseException: Error executing SQL update FOOBAR set customId = concat('cu:', (select uuid())) where customId is null limit 2: Duplicate entry 'cu:cde325da-f71f-11e5-95f8-d15a50829a7d' for key 'customId'
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:62)
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:122)
    at liquibase.database.AbstractJdbcDatabase.execute(AbstractJdbcDatabase.java:1206)
    at liquibase.database.AbstractJdbcDatabase.executeStatements(AbstractJdbcDatabase.java:1189)
    at liquibase.changelog.ChangeSet.execute(ChangeSet.java:518)
    ... 85 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'cu:cde325da-f71f-11e5-95f8-d15a50829a7d' for key 'customId'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1039)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2677)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2627)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:841)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:681)
    at com.mchange.v2.c3p0.impl.NewProxyStatement.execute(NewProxyStatement.java:1006)
    at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:310)
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:55)
    ... 89 more

请注意,customId 上当然有一个 UNIQUE 约束 - 但即使在使用 Liquibase 时,select uuid()(也尝试过不带选择的 uuid())不应该生成唯一值?

【问题讨论】:

    标签: mysql uuid liquibase unique-constraint


    【解决方案1】:

    这个问题可以通过一个小的解决方法来解决。我将更新分为两个查询:

    <changeSet id="v3.0.3" author="msp" runAlways="false">
        <preConditions onFail="MARK_RAN">
            <not>
                <sqlCheck expectedResult="0">select count(*) from FOOBAR where customId is null</sqlCheck>
            </not>
        </preConditions>
    
        <sql>update FOOBAR set customId = (select uuid())) where customId is null</sql>
        <sql>update FOOBAR set customId = concat('cu:', customId) where length(customId) = 36
    </changeSet>
    

    这当然只适用于我可以确定第一个查询的所有行都可以由length(customId) = 36 识别的情况。

    【讨论】:

      猜你喜欢
      • 2017-04-04
      • 2022-08-09
      • 2018-12-28
      • 1970-01-01
      • 2020-07-22
      • 2012-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多