在 Entity class 通过 Spring Data JPA 中更改时,Liquibase 不更新列数据类型

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

在 Spring Boot,Spring Data JPA 项目中,我有一个名为 Country 的实体 class,只有几列。我生成了变更日志并使用以下命令应用它

$ mvn process-test-resources

$ mvn process-resources

它使用 liquibase 和 liquibase-hibernate5 插件创建表

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;

}

我将 testCode 列数据类型从 Long 更新为 String in Country class 并使用上述命令生成变更集。应用变更集后,数据类型保持不变。这是 pom.xml 文件

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>


这一代使用 liquibase-hibernate5 的变更集不包括字段类型变更。如果您可以查看 changeset 文件,您将不会发现关于您的字段类型更改生成的 changesetliquibase-hibernate5 插件似乎不支持它。

  1. 看看这个class

  2. 中的评论
  3. 此插件的开发者正在 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.

  4. 目前的解决方案是手动添加 diff。以下代码摘自link

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