Warm tip: This article is reproduced from serverfault.com, please click

Liquibase validation fails when UNIQUE constraint

发布于 2020-11-28 11:15:39

I'm doing my training Spring MVC app. DB is PostgreSQL. I expect that Liquibase drops, re-creates, fills all schemas in DB on every run. At least when I make any changes (create, delete, edit of entities), on next run all of those changes desapear, as I expect. In my app Liquibase is taking commands from sql file. Now I need to add UNIQUE constraint to some of my schemes, like this

--liquibase formatted sql

--changeset oleg:create-multiple-tables splitStatements:true endDelimiter:;

DROP TABLE IF EXISTS university CASCADE;

CREATE TABLE university (
id BIGSERIAL PRIMARY KEY,
name TEXT,
UNIQUE (name)
);

After that liquibase is throwing liquibase.exception.ValidationFailedException. Here is stacktrace:

2020-12-01 19:14:45,473 [-127.0.0.1] [WARN ] [.s.AnnotationConfigWebApplicationContext] - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in com.foxminded.university.spring.config.SpringConfig: Invocation of init method failed; nested exception is liquibase.exception.ValidationFailedException: Validation Failed:
     1 change sets check sum
          classpath:createTables.sql::create-multiple-tables::oleg was: 8:a3395a596e6e92a1baeb0c6b507beb8d but is now: 8:e66b950dd66f44bf4107495d85bbe928

2020-12-01 19:14:45,477 [-127.0.0.1] [ERROR] [               o.s.w.s.DispatcherServlet] - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in com.foxminded.university.spring.config.SpringConfig: Invocation of init method failed; nested exception is liquibase.exception.ValidationFailedException: Validation Failed:
     1 change sets check sum
          classpath:createTables.sql::create-multiple-tables::oleg was: 8:a3395a596e6e92a1baeb0c6b507beb8d but is now: 8:e66b950dd66f44bf4107495d85bbe928

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1794)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:702)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:578)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170)
    at javax.servlet.GenericServlet.init(GenericServlet.java:158)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1144)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:988)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4885)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5199)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1720)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:287)
    at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:809)
    at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:479)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:428)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:287)
    at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:809)
    at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at java.management/com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:468)
    at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1466)
    at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1307)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:691)
    at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1406)
    at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:827)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
    at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
    at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:691)
    at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
    at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
    at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: liquibase.exception.ValidationFailedException: Validation Failed:
     1 change sets check sum
          classpath:createTables.sql::create-multiple-tables::oleg was: 8:a3395a596e6e92a1baeb0c6b507beb8d but is now: 8:e66b950dd66f44bf4107495d85bbe928

    at liquibase.changelog.DatabaseChangeLog.validate(DatabaseChangeLog.java:298)
    at liquibase.Liquibase.lambda$update$1(Liquibase.java:237)
    at liquibase.Scope.lambda$child$0(Scope.java:160)
    at liquibase.Scope.child(Scope.java:169)
    at liquibase.Scope.child(Scope.java:159)
    at liquibase.Scope.child(Scope.java:138)
    at liquibase.Liquibase.runInScope(Liquibase.java:2277)
    at liquibase.Liquibase.update(Liquibase.java:215)
    at liquibase.Liquibase.update(Liquibase.java:201)
    at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:321)
    at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:269)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1790)
    ... 62 common frames omitted

When I delete UNIQUE everything is working great again. Can you please help me to fix it so I could add UNIQUE constraint to my schemes?

Questioner
Oleg
Viewed
0
Oleg 2020-12-02 16:36:59

I found a solution to that problem. Guys in comments helped me to find wright path to solve that issue. I tried adding new changesets to the end of my existing sql file, like that:

ALTER TABLE university ADD CONSTRAINT unique_name UNIQUE (name);

But it didn't help. The solution that has helped me is command

mvn liquibase:clearCheckSums

in command line. After that I added UNIQUE (name) to my CREATE TABLE changeset. Now there are no exceptions on run, and exception throws when I try to create entity with existing name, as I expect.