A while ago, eXo introduced Liquibase to evolve the database schema safely in the product. A built-in component has been provided within the eXo commons project to let Liquibase perform database schema changes between versions of eXo Platform. However, it was designed to automate upgrades at runtime and not necessarily to support all kinds of operations that are needed at development time as an add-on developer iterates on his code.

At the heart of Liquibase is the Database Change Log File. It’s an xml file that contains instructions to track successive database schema updates. As an add-on developer, I found that manually maintaining it can be time consuming and error prone. Fortunately, I found a very handy maven plugin is available that made my life easier. If you are an eXo add-on developer, read on to learn how I remained highly productive, while dealing with a volatile database schema in an early-stage add-on project.

So what do you have for us?

Well, to be honest, there is no a silver bullet. BUT, Liquibase itself comes with a set of awesome features such as the Liquibase Maven plugin.

Instead of writing the change log file manually, we can use the Liquibase Maven plugin to generate it and save ourselves a lot of work. I want to illustrate this by means of an example. In the early stage of the development of a new eXo add-on I am currently working on, the data model was not always stable. It had to evolve frequently as I was implementing some moving requirements. Agility is cool, but updating the change log file quickly became a painful task for me.

With my team, we decided to use Liquibase Maven plugin as a ‘Swiss Army Knife’ for several common tasks, to:

Generate a changelog from an existing database

Generate a changelog from diff between two databases

Generate a changelog from diffs between a database and JPA entities

Generate a changelog from an existing database

The first step that every developer wants to test/validate is to generate a changelog from an existing database. Typically, you create your database schema with SQL commands or using an UI frontend and you need a way to easily replicate this in your development environment. In this situation liquibase-maven-plugin comes with a built-in Maven goal, called generateChangeLog

Command Line

mvn liquibase:generateChangeLog

Plugin Configuration

Configuring the plugin comes down to adding the following entry:<outputChangeLogFile> to the plugin’s configuration:

Generate a changelog from diff between two databases

In some situations, typically when we need to update a database schema already used in production, we can use the plugin to generate a changelog file from the differences between two existing databases:

The development database which contains the adaptation

The production database which contains the latest version of the schema

Command Line

mvn liquibase:diff

Plugin Configuration

Liquibase’s plugin configuration should be adapted as follows:

Add an entry <diffChangeLogFile> to specify where the changeLog will be generated

Configure base DB

1

2

3

4

5

<driver>com.mysql.jdbc.Driver</driver>

<url>jdbc:mysql://localhost:3306/tribe</url>

<defaultSchemaName>tribe</defaultSchemaName>

<username>root</username>

<password></password>

3. Configure reference DB

1

2

3

4

<referenceUrl>jdbc:mysql://localhost:3306/local</referenceUrl>

<referenceDriver>com.mysql.jdbc.Driver</referenceDriver>

<referenceUsername>root</referenceUsername>

<referencePassword></referencePassword>

Here’s a snippet of the plugin’s configuration we used within my addon :

The output is a changelog file that contains changes against the old schema.

Generate a changelog from diffs between a database and JPA entities

The most expected feature provided by Liquibase Maven Plugin when coupled with the Liquibase Hibernate Plugin is the way of generating the changelog from JPA entities. The goal is to generate a changelog file from the differences between an existing database (for example production) and our new persistence entities.

Note: It is important to emphasise that developers have to check the consistency of generated changesets and adapt them if necessary.

Command Line

mvn liquibase:diff

Plugin Configuration

The configuration is quite similar to the conf for 2 different databases, except for referenceUrl in which we are using JPA persistence unit instead of database url:

Master changelog generation

Use a standard entry point

When using Liquibase as part of a build automation scenario, I think it makes sense to create a single entry point for Liquibase to manage all generated changelog files that we will call XYZ.db.changelog-master.xml. The aim is to start from this file and load all other changesets available in src/main/resources/db/changelog.

The following snippet illustrates how we use a master changelog file within our add-on:

Note: As you may have noticed, we haven’t talked about liquibase:update option. Quite simply, this option is used to perform the schema changes listed in the changelog on the target database. For eXo projects, this use case was wrapped up within a core service called org.exoplatform.commons.persistence.impl.LiquibaseDataInitializer which is triggered at server startup.

Conclusion

Liquibase is a powerful tool to keep control of your database schema changes during your development lifecycle. Coupled with liquibase-maven-plugin, it offers a very useful way of generating changelog files seamlessly. Instead of writing the file manually, developers rely on this plugin to do the job, which is a huge time saver.