使用mvn liquibase:diff生成Spring Boot实体迁移时changeSets为0的问题
问题:执行
mvn liquibase:diff生成数据库迁移变更集为空(changeSets count: 0) 执行mvn liquibase:diff命令尝试从Spring Boot实体生成数据库迁移变更日志,但生成的文件为空,控制台输出:
changeSets count: 0
[INFO] No changesets to add.
相关配置与代码
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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>ch.Liquibase</groupId> <artifactId>Liquibase</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Liquibase</name> <description>Liquibase</description> <properties> <java.version>21</java.version> <spring-cloud.version>2023.0.0</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>3.2.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>3.2.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>4.24.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>8</source> <target>8</target> </configuration> </plugin> <plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>4.24.0</version> <configuration> <propertyFile>src/main/resources/liquibase/config/liquibase-development.properties</propertyFile> <promptOnNonLocalDatabase>true</promptOnNonLocalDatabase> </configuration> </plugin> </plugins> </build> </project>
liquibase-development.properties
changeLogFile=src/main/resources/liquibase/liquibase-changeLog.xml diffChangeLogFile=src/main/resources/liquibase/liquibase-diff-changeLog.xml outputChangeLogFile=src/main/resources/liquibase/liquibase-new-changeLog.xml url=jdbc:mysql://localhost:3306/liquibase_demo_db defaultSchemaName=liquibase_demo_db username=root password=123456 driver=com.mysql.cj.jdbc.Driver referenceDefaultSchemaName=liquibase_demo_ref referenceDriver=com.mysql.cj.jdbc.Driver referenceUrl=jdbc:mysql://localhost:3306/liquibase_demo_ref referenceUsername=root referencePassword=123456 liquibase.generateChangesetCreatedValues=true liquibase.pro.sql.inline=true liquibase.includeCatalogInSpecification=true liquibase.command.diffChangeLog.format=xml liquibase.command.diffChangeLog.skipDatabaseStep=true
application.properties
## Database Properties # Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) spring.datasource.url = jdbc:mysql://localhost:3306/liquibase_demo_db?useSSL=false spring.datasource.username = root spring.datasource.password = 123456 # Hibernate Properties spring.jpa.database-platform = org.hibernate.dialect.MySQL8Dialect # LIQUIBASE (LiquibaseProperties) spring.liquibase.change-log=classpath:liquibase/liquibase-changeLog.xml spring.datasource.initialization-mode=always spring.liquibase.default-schema=my_schema spring.jpa.properties.hibernate.default_schema=my_schema spring.liquibase.enabled=true
实体类 Customer.java
package com.example.demo.model; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; @Getter @Setter @Entity(name = "customers") public class Customer { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", nullable = false) private Long id; private String name; private String surname; private String address; }
启动类 DemoApplication.java
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
排查与解决方案
1. 修正Liquibase Diff的参考源逻辑
liquibase:diff默认是对比两个数据库的差异,当前配置用referenceUrl指向了另一个数据库liquibase_demo_ref,如果该库和目标库结构一致,自然不会生成变更集。要从JPA实体生成变更集,需要将Hibernate元数据作为参考源:
- 修改
liquibase-development.properties,替换原有reference配置:# 移除原reference相关配置,添加以下内容 referenceDriver=liquibase.ext.hibernate.database.connection.HibernateDriver referenceUrl=hibernate:spring:com.example.demo.model?dialect=org.hibernate.dialect.MySQL8Dialect - 在pom.xml中添加Liquibase Hibernate6扩展依赖(版本和liquibase-core一致):
<dependency> <groupId>org.liquibase.ext</groupId> <artifactId>liquibase-hibernate6</artifactId> <version>4.24.0</version> </dependency>
2. 统一Schema配置
application.properties中配置的默认schema是my_schema,但Liquibase配置文件中是liquibase_demo_db,两者不一致会导致对比失败:
- 将两处配置统一为同一个schema,比如修改application.properties:
spring.liquibase.default-schema=liquibase_demo_db spring.jpa.properties.hibernate.default_schema=liquibase_demo_db - 确保目标数据库中存在该schema(MySQL中需先手动创建)。
3. 修正Java版本与编译配置
pom.xml中java.version=21,但maven-compiler-plugin配置为source/target=8,版本不匹配会影响Liquibase读取Hibernate元数据:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>21</source> <target>21</target> <release>21</release> </configuration> </plugin>
4. 执行前的准备步骤
- 确保目标数据库
liquibase_demo_db中不存在customers表(若之前Hibernate自动建表,需手动删除); - 先执行
mvn compile编译实体类,保证Liquibase能读取到编译后的class文件; - 再执行
mvn liquibase:diff生成变更集。
内容的提问来源于stack exchange,提问作者Shafiqul Islam
相关产品推荐
相关产品推荐

