Using Liquibase with Hibernate

Hibernate is an object-relational mapping (ORM) tool that can be used alongside Liquibase to provide a persistent framework for a relational database.

The purpose of this document is to guide you through the process of creating a new Liquibase project and integrating it into your Hibernate ORM setup. In this tutorial, you will learn how to install the required database drivers and configure the liquibase.properties file to establish a connection to an H2 database.

Supported Versions

  • 3.X: liquibase-hibernate3
  • 4.0–4.2: liquibase-hibernate4.2
  • 4.3: liquibase-hibernate4
  • 5.0+: liquibase-hibernate5

Prerequisites

  • Ensure that you have installed the latest version of Liquibase. Find the appropriate executable for your platform.
  • Ensure that the Liquibase executable location is in the PATH environment variable. For more information, see Installing Liquibase.
  • Note: We will refer to the location of the Liquibase executable as $LIQUIBASE_HOME in this tutorial.

  • Download and install Maven.

Driver Information

Hibernate can be used with several databases that are supported by Liquibase, such as H2.

Supported Commands and Change Types

For information on supported Liquibase Commands and Liquibase Change Types, go to Liquibase Database Tutorials and select the type of database you are using Hibernate with.

Testing Your Connection

To start the H2 server included in the Liquibase distribution, open the command line, go to $LIQUIBASE_HOME/examples, and run liquibase init start-h2. This will open a database console in your browser.

You can check the status of the database by entering create table test_table (id int) in the text area of the database console and selecting Run. You will see TEST_TABLE appear in the object view. For more information, see Using Liquibase with H2 .

Creating a New Liquibase Project with Hibernate

We will be creating a Maven project for this tutorial. To configure a Liquibase project for Hibernate, perform the following steps:

  1. Install the Liquibase extension by copying the extension jar file into the $LIQUIBASE_HOME/lib directory.
  2. Create a project folder anywhere on your machine and name it HibernateLiquibase. The project folder will be used to store the Liquibase configuration files and changelogs.
  3. Create a liquibase.properties file and place it in your src/main/resources directory within the HibernateLiquibase folder.
  4. Note: For more information about the Liquibase properties file, see Specifying Properties in a Connection Profile.

    The liquibase.properties file should contain the following properties, along with the necessary authentication properties:

    changelog-file=dbchangelog.xml
    url=hibernate:ejb3:com.liquibase.hibernate.tutorial.jpa
    driver=liquibase.ext.hibernate.database.connection.HibernateDriver
    classpath=target\\hibernate-liquibase-0.0.1-SNAPSHOT.jar

    If you do not specify these in your liquibase.properties file, you must enter them as attributes in the command line.

    Note: Liquibase supports only the following special characters in passwords: ~ # $ % * ( ) - _ + [ ] { } . ?. Unsupported special characters are as follows: @ & / : < > " ' ` | ^ ! = , \ <spaces>.

    • If you placed your jar files in the liquibase/lib install directory, there is no need to specify the classpath property in the liquibase.properties file. Otherwise, put the path to your drivers as it is shown in the previous example.
    • If you have a Liquibase Pro License Key and want to apply it to your project, add the following property to your liquibase.properties file:
    • liquibaseProLicenseKey: <paste license key>
  5. Create a pom.xml file in the HibernateLiquibase folder and add the following content to the file:
  6. <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    
    	<groupId>com.liquibase</groupId>
    	<artifactId>hibernate-liquibase</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>Liquibase Hibernate Example</name>
    	<description>Demo project for liquibase and hibernate</description>
    
    		<properties>
    			<liquibase.version>4.3.5</liquibase.version>
    			<liquibase-hibernate5.version>4.3.5</liquibase-hibernate5.version>
    			<javassist.version>3.24.0-GA</javassist.version>
    			<validation-api.version>2.0.1.Final</validation-api.version>
    			<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
    			<spring-boot.version>2.3.4.RELEASE</spring-boot.version>
    			<hibernate5.version>5.5.3.Final</hibernate5.version>
    			<maven.compiler.source>11</maven.compiler.source>
    			<maven.compiler.target>11</maven.compiler.target>
    			<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		</properties>
    
    		<dependencies>
    			<dependency>
    				<groupId>org.hibernate</groupId>
    				<artifactId>hibernate-core</artifactId>
    				<version>${hibernate5.version}</version>
    			</dependency>
    			<dependency>
    				<groupId>com.h2database</groupId>
    				<artifactId>h2</artifactId>
    				<version>1.4.200</version>
    			</dependency>
    		</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.codehaus.mojo</groupId>
    				<artifactId>exec-maven-plugin</artifactId>
    				<version>3.0.0</version>
    				<configuration>
    					<executable>java</executable>
    					<arguments>
    						<argument>-classpath</argument>
    						<classpath/>
    						<argument>com.liquibase.Application</argument>
    					</arguments>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.liquibase</groupId>
    				<artifactId>liquibase-maven-plugin</artifactId>
    				<version>${liquibase.version}</version>
    				<configuration>
    					<changelog-file>${project.basedir}/src/main/resources/config/liquibase/master.xml</changelog-file>
    					<outputChangeLogFile>dbchangelog.xml</outputChangeLogFile>
    					<diffChangeLogFile>${project.basedir}/src/main/resources/db/migrations/${maven.build.timestamp}_changelog.xml</diffChangeLogFile>                   
    					<propertyFile>liquibase.properties</propertyFile>
    					<logging>debug</logging>
    					<contexts>!test</contexts>
    				</configuration>
    				<dependencies>
    					<dependency>
    						<groupId>org.liquibase</groupId>
    						<artifactId>liquibase-core</artifactId>
    						<version>${liquibase.version}</version>
    					</dependency>
    					<dependency>
    						<groupId>org.liquibase.ext</groupId>
    						<artifactId>liquibase-hibernate5</artifactId>
    						<version>${liquibase-hibernate5.version}</version>
    					</dependency>
    					<dependency>
    						<groupId>org.springframework.boot</groupId>
    						<artifactId>spring-boot-starter-data-jpa</artifactId>
    					<version>${spring-boot.version}</version> 
    				 </dependency>
    					<dependency> 
    						<groupId>javax.validation</groupId>
    						<artifactId>validation-api</artifactId>  
    						<version>${validation-api.version}</version> 
    					</dependency>
    					<dependency>
     						<groupId>org.javassist</groupId>
    						<artifactId>javassist</artifactId>
    						<version>${javassist.version}</version>
    					</dependency>
    				</dependencies>
    			</plugin>
    		</plugins>
    	</build>
    </project>
  7. Get the additional dependencies by running the following command from the same directory as the pom.xml file:
  8. mvn dependency:copy-dependencies -DoutputDirectory=${project.build.directory}/lib -Dhttps.protocols=TLSv1.2

    Copy the following jars from ./target/lib to $LIQUIBASE_HOME/lib:

    • byte-buddy-1.10.10.jar
    • classmate-1.5.1.jar
    • dom4j-2.1.3.jar
    • hibernate-commons-annotations-5.1.0.Final.jar
    • hibernate-core-5.4.21.Final.jar
    • jandex-2.1.3.Final.jar
    • javax.persistence-api-2.2.jar
    • jboss-logging-3.3.2.Final.jar
    • jboss-transaction-api_1.2_spec-1.1.1.Final.jar
  9. Create a JPA configuration file at META-INF/persistence.xml. The persistence.xml file should contain the following content:
  10. <persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
    	<persistence-unit name="com.liquibase.hibernate.tutorial.jpa" transaction-type="RESOURCE_LOCAL">
    		<properties>
    			<property name="javax.persistence.schema-generation.database.action" value="none" />
    			<property name="javax.persistence.provider" value="org.hibernate.jpa.HibernatePersistenceProvider" />
    			<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
    			<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost:9090/mem:dev" />
    			<property name="javax.persistence.jdbc.user" value="dbuser" />
    			<property name="javax.persistence.jdbc.password" value="letmein" />
    			<property name="hibernate.connection.handling_mode" value="delayed_acquisition_and_release_after_transaction" />
    		</properties>
    	</persistence-unit>
    </persistence>
  11. Create the folder src/main/java/com/liquibase, which will be used for entity classes. In this directory, create a file House.java in a text editor and add the following content:
  12. package com.liquibase;
    	
    	import java.io.Serializable;
    	import javax.persistence.*;
    	@Entity
    	public class House implements Serializable {
    		private static final long serialVersionUID = 1L;
    		@Id
    		@GeneratedValue
    		private Integer id;
    		private String owner;
    		private boolean fullyPaid;
    	
    		public Integer getId() {
    		return id;
    		}
    	
    		public void setId(Integer id) {
    		this.id = id;
    		}
    	
    		public String getOwner() {
    		return owner;
    		}
    	
    		public void setOwner(String owner) {
    		this.owner = owner;
    		}
    	
    		public boolean isFullyPaid() {
    		return fullyPaid;
    		}
    	
    		public void setFullyPaid(boolean fullyPaid) {
    		this.fullyPaid = fullyPaid;
    		}
    	
    	}
    
  13. Create a second file Item.java in the same directory and paste the following:
  14. package com.liquibase;
                
    	import java.io.Serializable;
        import javax.persistence.*;
        @Entity
        public class Item implements Serializable {
        	private static final long serialVersionUID = 1L;
            @Id
            @GeneratedValue
            private Integer id;
            private String name;
            @ManyToOne
            private House house;
    
            public Integer getId() {
            	return id;
            }
    
            public void setId(Integer id) {
            this.id = id;
            }
    
            public String getName() {
            return name;
            }
    
            public void setName(String name) {
            this.name = name;
            }
    
    		public House getHouse() {
    		return house;
    		}
    
    		public void setHouse(House house) {
    		this.house = house;
    		}
    
    	}
  15. If you haven't already, first install the application using the mvnw install command, or mvnw.cmd install for Windows. The generated jar is what is referenced in the liquibase.properties file:

  16. classpath=target\\hibernate-liquibase-0.0.1-SNAPSHOT.jar
  17. Next, generate a dbchangelog.xml file from Hibernate in the HibernateLiquibase project folder:

  18. liquibase --log-level=INFO --defaultsFile=src/main/resources/liquibase.properties generate-changelog
  19. Verify the project configuration by running the Liquibase status command. Open a command prompt and go to the project folder. Run the following command:
  20. liquibase --log-level=INFO --defaultsFile=src/main/resources/liquibase.properties status

    Example Output

    Liquibase command 'status' was executed successfully.
  21. Verify that the DATABASECHANGELOG and DATABASECHANGELOGLOCK tables were created.
  22. Using a database UI tool, you should see the new Liquibase tables.

    From a database UI tool, ensure that your database contains the table you added along with the DATABASECHANGELOG table and DATABASECHANGELOGLOCK table.

Congratulations!

You have successfully configured your project and can begin creating changesets to migrate changes to your database using Hibernate.

Source code is available at: https://github.com/juliuskrah/hibernate-liquibase

Related Links