Using Liquibase with Hibernate

Note: This database is supported at or below the Contributed level. Functionality may be limited. Databases at the Contributed level are not supported by the Liquibase support team. Best-effort support is provided through our community forums.

For more information about the verification levels, see Database Verification and Support.

If you have an update to these instructions, submit feedback so we can improve the page.

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 JPA setup.

Supported database versions

  • 6.x: liquibase-hibernate6
  • 5.x: liquibase-hibernate5

Prerequisites

  1. Introduction to Liquibase – Dive into Liquibase concepts.
  2. Install Liquibase – Download Liquibase on your machine.
  3. Get Started with Liquibase – Learn how to use Liquibase with an example database.
  4. Design Your Liquibase Project – Create a new Liquibase project folder and organize your changelogs
  5. How to Apply Your Liquibase Pro License Key – If you use Liquibase Pro, activate your license.
  • Download and install Maven.

Create 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. Specify the database URL in the liquibase.properties file (defaults file), along with other properties you want to set a default value for. Liquibase does not parse the URL. You can either specify the full database connection string or specify the URL using your database's standard JDBC format:
  2. url=hibernate:ejb3:com.liquibase.hibernate.tutorial.jpa

    Tip: To apply a Liquibase Pro key to your project, add the following property to the Liquibase properties file: licenseKey: <paste code here>

  3. Create a pom.xml file in your project directory and add the following content to the file:
  4. pom.xml
    <?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>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>3.0.0</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <liquibase.version>4.18.0</liquibase.version>
            <liquibase-hibernate6.version>4.18.0</liquibase-hibernate6.version>
            <hibernate6.version>6.1.5.Final</hibernate6.version>
            <javassist.version>3.24.0-GA</javassist.version>
            <validation-api.version>3.0.2</validation-api.version>
            <maven.compiler.source>11</maven.compiler.source>
            <maven.compiler.target>11</maven.compiler.target>
            <maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.hibernate.orm</groupId>
                <artifactId>hibernate-core</artifactId>
                <version>${hibernate6.version}</version>
            </dependency>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
            </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>
                        <changeLogFile>master.xml</changeLogFile>
                        <outputChangeLogFile>dbchangelog.xml</outputChangeLogFile>
                        <diffChangeLogFile>
                            ${project.basedir}/src/main/resources/db/migrations/${maven.build.timestamp}_changelog.xml
                        </diffChangeLogFile>
                        <propertyFile>src/main/resources/spring.properties</propertyFile>
                        <logging>debug</logging>
                    </configuration>
                    <dependencies>
                        <dependency>
                            <groupId>org.liquibase</groupId>
                            <artifactId>liquibase-core</artifactId>
                            <version>${liquibase.version}</version>
                        </dependency>
                        <dependency>
                            <groupId>org.liquibase.ext</groupId>
                            <artifactId>liquibase-hibernate6</artifactId>
                            <version>${liquibase-hibernate6.version}</version>
                        </dependency>
                        <dependency>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-starter-data-jpa</artifactId>
                            <version>3.0.0</version>
                        </dependency>
                        <dependency>
                            <groupId>jakarta.validation</groupId>
                            <artifactId>jakarta.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>
  5. Create a JPA configuration file at META-INF/persistence.xml. The persistence.xml file should contain the following content:
  6. persistence.xml
    <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="jakarta.persistence.schema-generation.database.action" value="none" />
                <property name="jakarta.persistence.provider" value="org.hibernate.jpa.HibernatePersistenceProvider" />
                <property name="jakarta.persistence.jdbc.driver" value="org.h2.Driver" />
                <property name="jakarta.persistence.jdbc.url" value="jdbc:h2:file:~/test" />
                <property name="jakarta.persistence.jdbc.user" value="dbuser" />
                <property name="jakarta.persistence.jdbc.password" value="letmein" />
                <property name="hibernate.connection.handling_mode" value="delayed_acquisition_and_release_after_transaction" />
            </properties>
        </persistence-unit>
    </persistence>
  7. Create the folder src/main/java/com/liquibase, which will be used for entity classes.

    In this directory, open a text editor to create a file named House.java and add the content from the following code block.

    This is a simple example of an Entity, with a generated Id value. This class will be used in the next Entity.
  8. House.java
    package com.liquibase;
    
        import java.io.Serializable;
        import jakarta.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;
            }
    
        }
  9. Create a second file Item.java in the same directory and add the content from the following code block.

    This Entity includes a many-to-one relationship: each House can be related to many Items.
  10. Item.java
    package com.liquibase;
    
        import java.io.Serializable;
        import jakarta.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;
            }
    
        }
  11. Install the application using the mvnw install command, or mvnw.cmd install for Windows.
  12. The generated JAR is what is referenced in the liquibase.properties file: classpath=target\\hibernate-liquibase-0.0.1-SNAPSHOT.jar
  13. Next, generate a dbchangelog.xml file from Hibernate in your project folder:
  14. mvn liquibase:diff
  15. A file will be generated at src/main/resources/db/migrations/20221208174852_changelog.xml. You can move and rename it to src/main/resources/dbchangelog.xml, then run mvn install again.
  16. Verify the project configuration by running the Liquibase status command. Open a command prompt and go to the project folder. Run the following command:
  17. mvn liquibase:status
    Example output:
    5 changesets have not been applied to DBUSER@jdbc:h2:file:~/test
  18. Now apply the changeset using the command
  19. mvn liquibase:update
  20. From a database UI tool, ensure that your database contains the table you added along with the DATABASECHANGELOG table and DATABASECHANGELOGLOCK table.
  21. You can run the application using command mvn exec:exec and it shall work successfully.

Finished

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