javaspring-data-jpaliquibaseliquibase-hibernate

Liquibase not updating column data type when changed in Entity class through Spring Data JPA


In the Spring Boot, Spring Data JPA project, I have an entity class named Country with few columns. I generated changelog and applied it with the following commands

$ mvn process-test-resources

$ mvn process-resources

It created tables using liquibase and liquibase-hibernate5 plugins

Country.java

package com.liquibasedemo.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import javax.persistence.*;


@Entity
@Table(name = "country")
@Data
public class Country
{
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "code")
    private String code;

    @Column(name = "iso_code")
    private String isoCode;

    @Column(name = "test_code")
    private String testCode;


    @ManyToOne
    @JoinColumn(name = "region_id")
    @JsonIgnore
    private Region region;

}

I updated testCode column data type from Long to String in Country class and used the above commands to generate changeset. After applying changeset, the datatype remains unchanged. Here is the pom.xml file

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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com</groupId>
    <artifactId>liquibasedemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>liquibasedemo</name>
    <description>Liquibase Demo project with Spring Boot and Spring Data</description>

    <properties>
        <spring-boot.version>2.1.5.RELEASE</spring-boot.version>
        <hibernate.version>5.4.3.Final</hibernate.version>
        <liquibase-maven-plugin.version>3.5.5</liquibase-maven-plugin.version>
        <liquibase-hibernate5.version>3.6</liquibase-hibernate5.version>
        <validation-api.version>2.0.1.Final</validation-api.version>
        <javassist.version>3.24.0-GA</javassist.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-envers</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>



    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.liquibase</groupId>
                <artifactId>liquibase-maven-plugin</artifactId>
                <version>${liquibase-maven-plugin.version}</version>
                <configuration>
                    <propertyFile>src/main/resources/liquibase.properties</propertyFile>
                    <changeLogFile>src/main/resources/db/db.changelog-master.xml</changeLogFile>
                    <diffChangeLogFile>src/main/resources/db/changelog/${maven.build.timestamp}_changelog.xml</diffChangeLogFile>
                    <logging>info</logging>
                </configuration>

                <executions>
                    <execution>
                        <id>update-profile</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>update</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>diff-profile</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>diff</goal>
                        </goals>
                    </execution>
                </executions>

                <dependencies>
                    <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>



Solution

  • This generation of changeset using liquibase-hibernate5 does not include the field type changes. If you can see into the changeset file you will not find the changeset generated regarding your field type change. It seems to be not supported by the liquibase-hibernate5 plugin.

    1. Have a look at the comments in this class

    2. The developer of this plugin is discussing about it at link

      The reason these tend to be ignored is because how hibernate represents the datatype is usually different than how the database represents the datatype even when they are actually the same. I'm looking at ways to improve this with Liquibase 4.

    3. Solution for now would be to add the diff manually. The following code is taken from link

      <changeSet author="liquibase-docs" id="modifyDataType-example">
          <modifyDataType catalogName="cat"
                  columnName="id"
                  newDataType="int"
                  schemaName="public"
                  tableName="person"/>
      </changeSet>