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
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.
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.
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With