user979051
user979051

Reputation: 1267

Liquibase Auto Rollback

I'm working on a branch and for instance need to delete a column in table X, I add a change and its good for that specific branch, then I switch to another branch that still requires that column and that change needs to be rolled back. There are a lot of changes to the db such as this from branch to branch.

I add a new changelog xml for every branch and include it in the master changelog xml. Obviously when I switch to another branch the changlog xml for the previous branch is no longer in the workspace and liquibase does not save the actual changeset in the database only its name and when it was applied, thus it won't be able to rollback changes automatically.

I'm using the Liquibase Servlet to apply changes on start up of my application.

Liquibase experts, is there an easy solution to this problem already implemented? Thank you!

Upvotes: 1

Views: 2955

Answers (1)

Mark O'Connor
Mark O'Connor

Reputation: 77951

It's difficult to share a single database instance across branches of your code. It causes the same sorts of problems, if you tried sharing the database across multiple developers.

Liquibase is designed to use the file based changesets as the master record for database change. The special table DATABASECHANGELOG is designed track which changesets have been applied to the database instance. Switching between branches causes confusion in lots of unpredictable ways, for example:

  • Missing changesets
  • Changesets whose content has changed (Leads to checksum errors).
  • ...

The best advice is to refresh or resync the database, whenever you switch between branches:

liquibase dropAll
liquibase update

In your case the second operation is probabily unnecessary as the liquibase servlet would update the database on startup.

If you have concerns about losing data, then use contexts to control test data.

Update

If you're using Maven this "resync" operation can be called from Maven as follows:

mvn -Presync compile

This profile is configured within your POM as follows:

    <profile>
        <id>resync</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.liquibase</groupId>
                    <artifactId>liquibase-maven-plugin</artifactId>
                    <version>${liquibase.plugin.version}</version>
                    <executions>
                        <execution>
                            <phase>process-resources</phase>
                            <configuration>
                                <url>${liquibase.url}</url>
                                <driver>${liquibase.driver}</driver>
                                <username>${liquibase.username}</username>
                                <password>${liquibase.password}</password>
                                <changeLogFile>${liquibase.changeLogFile}</changeLogFile>
                                <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
                            </configuration>
                            <goals>
                                <goal>dropAll</goal>
                                <goal>update</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>

Upvotes: 3

Related Questions