Hi everyone! Today we’ll be discussing about how you can integrate Liquibase into your application so that it automatically updates your database. That is especially interesting when you build smaller applications that don’t run in a highly regulated enterprise environment.
In these situations, it’s often not possible to run the update process yourself. And there might be no operations team which executes the SQL scripts. So, you need to run the database update automatically when you start your application. There are several ways to do that.
How to integrate Liquibase
If you’re building a plain Java application, you can use the Liquibase API to trigger the update. And it’s get even easier, if you’re using a CDI container. For example, in a Java EE application server or Spring. I will show you all 3 approaches in this tutorial.
Let’s start with the plain Java environment. Before you can use the Liquibase API, you need to add the required dependencies to your application. The following maven coordinates add the Liquibase core component in version 3.5.3 to your project.
After you’ve done that, you can implement the database migration in the following 3 steps:
- Get DB connection
- Initialise Liquibase
- Run the update
Getting the database connection
Getting the database connection obviously depends on your environment and technology stack. In this tutorial, I will show you how to do that with Hibernate 5. If you’re using Hibernate, you already configured the database connection in you Hibernate configuration. You probably also want to use Hibernate’s database validation to make sure that your mapping fits the database. You can do that by adding Liquibase to your startup process and execute the update before you create a SessionFactory.
First, you need to build a StandardServiceRegistry and use it to instantiate a MetadataSources object. I don’t provide any configuration when calling these methods. And Hibernate reads the hibernate.cfg.xml file from the classpath.
In the next step, you can use the MetadataSources object to get an instance of a ConnectionProvider service and retrieve a java.sql.Connection. Hibernate created this connection based on the configuration data in the hibernate.cfg.xml file. You can then use the Connection object to create a Liquibase-specific JdbcConnection.
Now you have everything you need to initialise Liquibase.
You first need to create a database object. Then provide the name of the changelog file, a ClassLoaderResourceAccessor and the database object.
Run the update
Then, you can call the update method with a reference to the context you want to use for your database update. After you’ve updated your database, you can follow Hibernate’s standard bootstrapping process. You therefore use the MetadataSources object to build your MetaData and build a SessionFactory. That’s all you need to do to integrate Liquibase into you Java SE application.
Every time you start the application, Liquibase will check the database and perform the required updates.
Integrating Liquibase into your Spring Boot application is extremely easy. You just have to add the Liquibase Core to your classpath. That’s all you need to do. The Liquibase integration will automatically load the master changelog file from the db changelog directory.
Adding Liquibase and CDI integration
The CDI integration is also a lot easier than integrating Liquibase into a plain Java SE application. But it requires a little more work than the Spring Boot integration. You need to add these 2 following dependencies to your project and include them in your deployment.
After you’ve done that, you need to implement a CDI bean with 3 producer methods. Let’s get into the IDE and take a closer look at it. You can see the CDI bean below. It implements a producer method for a CDILiquibaseConfig, a DataSource and a ResourceAccessor object. The CDILiquibaseConfig object contains a reference to the master changelog file.
So, please make sure that you reference a file within your deployment uni. Or you can use an external path which you can access from within the CDI container on all machines.
The producer of the DataSource object is simple. It just returns the object that I injected. And in the producer of the ResourceAccessor object, I use the class loader of the current bean to instantiate a new ClassLoaderResourceAccessor. That’s all you need to do.
When you deploy this application into a CDI container, Liquibase will run during the deployment and update the database. That was probably a lot easier than you expected when I told you that you need to implement 3 producer methods.
That’s all for now. I hope this article was useful to you. Please feel free to drop any comments, questions or suggestions.