Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Liquibase tried to apply all changeset, even if database is present

I am using Spring-Liquibase to perform any migration that is needed on the staging database.

The applicationContext.xml looks like

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.yahoo.comma"/>
    <bean id="liquibase" class="liquibase.integration.spring.SpringLiquibase">
        <property name="dataSource" ref="dataSource"/>
        <property name="changeLog" value="classpath:liquibase/changelog.xml"/>
        <property name="defaultSchema" value="pryme_dev"/>
    </bean>
</beans>

When I deploy the war file, i see errors in log as

INFO 6/11/14 9:32 AM:liquibase: Successfully acquired change log lock
INFO 6/11/14 9:32 AM:liquibase: Reading from pryme_dev.DATABASECHANGELOG
INFO 6/11/14 9:32 AM:liquibase: Reading from pryme_dev.DATABASECHANGELOG
INFO 6/11/14 9:32 AM:liquibase: Reading from pryme_dev.DATABASECHANGELOG
INFO 6/11/14 9:32 AM:liquibase: liquibase/changelog.xml: liquibase/2014/1-1.xml::05192014.1525::harith: Reading from pryme_dev.DATABASECHANGELOG
SEVERE 6/11/14 9:32 AM:liquibase: liquibase/changelog.xml: liquibase/2014/1-1.xml::05192014.1525::harith: Change Set liquibase/2014/1-1.xml::05192014.1525::harith failed.  Error: Error executing SQL CREATE TABLE pryme_dev.network (id INT NOT NULL, network_id BIGINT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, display_name VARCHAR(255) NOT NULL, active TINYINT(1) DEFAULT 1 NOT NULL, created_at TIMESTAMP DEFAULT NOW() NOT NULL, updated_at TIMESTAMP DEFAULT '1970-01-01 00:00:01' NOT NULL, created_by VARCHAR(50) DEFAULT 'pryme_user' NULL, updated_by VARCHAR(50) DEFAULT 'pryme_user' NULL, CONSTRAINT PK_NETWORK PRIMARY KEY (id)): Table 'network' already exists
liquibase.exception.DatabaseException: Error executing SQL CREATE TABLE pryme_dev.network (id INT NOT NULL, network_id BIGINT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, display_name VARCHAR(255) NOT NULL, active TINYINT(1) DEFAULT 1 NOT NULL, created_at TIMESTAMP DEFAULT NOW() NOT NULL, updated_at TIMESTAMP DEFAULT '1970-01-01 00:00:01' NOT NULL, created_by VARCHAR(50) DEFAULT 'pryme_user' NULL, updated_by VARCHAR(50) DEFAULT 'pryme_user' NULL, CONSTRAINT PK_NETWORK PRIMARY KEY (id)): Table 'network' already exists
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:61)
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:106)
    at liquibase.database.AbstractJdbcDatabase.execute(AbstractJdbcDatabase.java:1189)
    at liquibase.database.AbstractJdbcDatabase.executeStatements(AbstractJdbcDatabase.java:1172)
    at liquibase.changelog.ChangeSet.execute(ChangeSet.java:352)
    at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:40)
    at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:64)
    at liquibase.Liquibase.update(Liquibase.java:202)
    at liquibase.Liquibase.update(Liquibase.java:181)
    at com.yahoo.comma.persistence.DataSetupTest.liquibaseUpdate(DataSetupTest.java:53)
    at com.yahoo.comma.integration.IT1DataSetup.generateDataSet(IT1DataSetup.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:236)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:134)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:113)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:103)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:74)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'network' already exists
    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:406)
    at com.mysql.jdbc.Util.getInstance(Util.java:381)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1030)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2536)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2465)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:734)
    at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
    at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
    at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:294)
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:54)
    ... 44 more
INFO 6/11/14 9:32 AM:liquibase: liquibase/2014/1-1.xml::05192014.1525::harith: Successfully released change log lock
09:32:14.299 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@3ba0fcf

Questions
- Why is it applying all the changesets when database is already populated and that the database has DATABASECHANGELOG file present?
- How do I resolve this issue?

Thanks

like image 249
daydreamer Avatar asked Jun 11 '14 16:06

daydreamer


People also ask

Does Liquibase auto-commit?

Liquibase attempts to execute each changeset in a transaction that is committed at the end, or rolled back if there is an error. Some databases will auto-commit statements which interferes with this transaction setup and could lead to an unexpected database state.

Does Liquibase lock database?

Liquibase uses the DATABASECHANGELOGLOCK table to ensure only one instance of Liquibase runs at a time. When you make a database update, Liquibase reads from the DATABASECHANGELOG table to determine which changesets need to run.


2 Answers

The problem is often because part of the unique identifier for each changeSet is the path to the changelog file. It looks like it currently sees it as "liquibase/2014/1-1.xml".

If you run select * from databasechangelog where id='05192014.1525' what is the path already in the database?

like image 87
Nathan Voxland Avatar answered Oct 14 '22 22:10

Nathan Voxland


Just adding new, more direct info on why the issue happens.

Liquibase DATABASECHANGELOG Documentation

Liquibase uses the DATABASECHANGELOG table to track which changeSets have been ran.

The table tracks each changeSet as a row, identified by a combination of the “id”, “author” and a “filename” column which stores the path to the changelog file.

Please note that the filename column stores the path to the changelog. This may be an absolute path or a relative path depending on how the changelog was passed to Liquibase. For best results, it should be a relative path.

If you move the database, as in the case of migrating, and the filename column contains full paths, Liquibase may not recognize the changeset from the DATABASECHANGELOG table.

like image 44
Andy Refuerzo Avatar answered Oct 14 '22 23:10

Andy Refuerzo