Matt Slavicek
Matt Slavicek

Reputation: 881

How to roll back a database change with Liquibase using classpath

My application is using Liquibase to manage database changes. It sets up Liquibase like so:

@Bean(name = "liquibase")
public SpringLiquibase liquibaseData() {
    final SpringLiquibase liquibase = new SpringLiquibase();
    liquibase.setDataSource(dataSource);
    liquibase.setChangeLog("classpath:/db/changelog/db.changelog-master.xml");
    return liquibase;
}

It currently has a single changeset. When the changeset gets applied by running the application, a record is inserted into DATABASECHANGELOG as expected with a FILENAME of classpath:/db/changelog/0.0.1/db.changelog.xml

When I execute a liquibase rollbackCount 1, the response is Liquibase Rollback Successful, but the change did not get rolled back.

After manually rolling back the change (deleting the table created by the changeset), I do a liquibase update. The update is successful, but the FILENAME is db/changelog/0.0.1/db.changelog.xml. I execute a liquibase rollbackCount 1, and the change is rolled back as expected.

This is my liquibase.properties:

driver: oracle.jdbc.driver.OracleDriver
classpath: ../../../../../client-ui/build/libs/client-ui.war
url: jdbc:oracle:thin:@localhost:1521/orcl
username: the-username
password: the-password
changeLogFile: classpath:/db/changelog/db.changelog-master.xml

The crux of the problem seems to be that the FILENAME is different when the changeset is applied by the application versus the command line. How do I configure the command line parameters so it will create a DATABASECHANGELOG record with the same FILENAME as what the application creates?

Upvotes: 1

Views: 2328

Answers (1)

Nathan Voxland
Nathan Voxland

Reputation: 15763

Yes, the problem is that FILENAME is different. Spring sometimes includes the classpath: in their URL which Liquibase just uses. There is code in Liquibase to try to handle the "sometimes there classpath:" prefix, but it sounds like that is not handled correctly in the rollback logic.

There have been some improvements to how the classpath prefix is handled in recent versions, have you tried with Liquibase 3.4.0?

Otherwise, Liquibase update through spring should work correctly with or without the classpath prefix, so if you fix the FILENAME field you should be good. Something like UPDATE DATABASECHANGELOG SET FILENAME = SUBSTR(FILENAME, 10) WHERE FILENAME LIKE 'classpath:%' if you are using mysql. You could put a runAlways=true changeSet at the bottom of your changelog file to have it automatically clean up the paths on each update.

Upvotes: 2

Related Questions