Spring Boot3集成Liquibase执行diff报错:Unknown database Hibernate
使用Spring Boot 3搭配Spring Data JPA(MySQL 8),尝试通过Liquibase的liquibase:diff命令基于JPA实体生成变更日志时,出现如下错误:
Starting Liquibase at 15:54:24 (version 4.24.0 #14062 built at 2023-09-28 12:18+0000)
[INFO] Cannot load service: liquibase.database.Database: liquibase.ext.hibernate.database.HibernateSpringBeanDatabase Unable to get public no-arg constructor
[INFO] Cannot load service: liquibase.database.Database: liquibase.ext.hibernate.database.HibernateSpringPackageDatabase Unable to get public no-arg constructor
[INFO] Parsing Liquibase Properties File ./src/main/resources/liquibase.properties for changeLog parameters
[INFO] Executing on Database: jdbc:mysql://localhost:3306/liquibasetest
[WARNING] Unknown database: Hibernate
[INFO] Performing Diff on database root@localhost @ jdbc:mysql://localhost:3306/liquibasetest (Default Schema: liquibasetest)
[WARNING] Potentially ignored key(s) in property file ./src/main/resources/liquibase.propertieschangeLogFile'
'outputChangeLogFile'
[INFO] Error getting default schema
java.lang.NullPointerException
at liquibase.executor.jvm.JdbcExecutor$QueryCallableStatementCallback.doInCallableStatement (JdbcExecutor.java:579)
at liquibase.executor.jvm.JdbcExecutor.execute (JdbcExecutor.java:131)
at liquibase.executor.jvm.JdbcExecutor.query (JdbcExecutor.java:219)
at liquibase.execexecutor.jvm.JdbcExecutor.query (JdbcExecutor.java:230)
at liquibase.executor.jvm.JdbcExecutor.queryForObject (JdbcExecutor.java:238)
at liquibase.executor.jvm.JdbcExecutor.queryForObject (JdbcExecutor.java:253)
at liquibase.executor.jvm.JdbcExecutor.queryForObject (JdbcExecutor.java:248)
当前配置文件
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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>liquibase.learn</groupId> <artifactId>server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>server</name> <description>Demo project for Spring Boot</description> <properties> <java.version>17</java.version> <liquibase.propertyFile>${project.basedir}\src\main\resources\liquibase.properties</liquibase.propertyFile> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> </dependency> --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </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> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> <plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>4.24.0</version> <configuration> <propertyFileWillOverride>true</propertyFileWillOverride> <propertyFile>./src/main/resources/liquibase.properties</propertyFile> <!-- <changeLogFile>./src/main/resources/db/changelog.yaml</changeLogFile> <outputChangeLogFile>./src/main/resources/db/changelog.yaml</outputChangeLogFile> <referenceDriver>liquibase.ext.hibernate.database.connection.HibernateDriver</referenceDriver> <referenceUrl>hibernate:spring:liquibase.learn.server?dialect=org.hibernate.dialect.MySQLDialect&amp;hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&amp;hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy</referenceUrl> <driver>com.mysql.cj.jdbc.Driver</driver> --> </configuration> <dependencies> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>4.24.0</version> </dependency> <dependency> <groupId>org.liquibase.ext</groupId> <artifactId>liquibase-hibernate6</artifactId> <version>4.24.0</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.4.0.CR1</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
liquibase.properties
url=jdbc:mysql://localhost:3306/liquibasetest username=root password=password driver=com.mysql.cj.jdbc.Driver referenceDriver=liquibase.ext.hibernate.database.connection.HibernateDriver referenceUrl=hibernate:spring:liquibase.learn.server?dialect=org.hibernate.dialect.MySQLDialect&amp;hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&amp;hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy changeLogFile=./src/main/resources/db/changelog.yaml outputChangeLogFile=./src/main/resources/db/changelog.yaml
需求:创建/修改JPA实体后,自动生成对应的Liquibase变更日志。
修复步骤
1. 修正liquibase.properties中的转义错误
properties文件不需要HTML转义,referenceUrl中的&amp;需改为&,否则会导致参数解析失败,出现Potentially ignored key(s)警告:
referenceUrl=hibernate:spring:liquibase.learn.server?dialect=org.hibernate.dialect.MySQLDialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
2. 统一Hibernate版本,避免兼容性问题
Spring Boot 3.1.5默认依赖Hibernate 6.2.13.Final,手动指定的6.4.0.CR1版本不匹配会引发反射错误。删除liquibase-maven-plugin中手动添加的hibernate-core依赖,让Spring Boot管理版本:
<dependencies> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>4.24.0</version> </dependency> <dependency> <groupId>org.liquibase.ext</groupId> <artifactId>liquibase-hibernate6</artifactId> <version>4.24.0</version> </dependency> <!-- 移除手动指定的hibernate-core依赖 --> </dependencies>
3. 启用pom.xml中注释的Liquibase配置项
将liquibase-maven-plugin里注释的配置打开,确保参数正确传递(注意pom.xml中URL的转义符用&):
<configuration> <propertyFileWillOverride>true</propertyFileWillOverride> <propertyFile>./src/main/resources/liquibase.properties</propertyFile> <changeLogFile>./src/main/resources/db/changelog.yaml</changeLogFile> <outputChangeLogFile>./src/main/resources/db/changelog.yaml</outputChangeLogFile> <referenceDriver>liquibase.ext.hibernate.database.connection.HibernateDriver</referenceDriver> <referenceUrl>hibernate:spring:liquibase.learn.server?dialect=org.hibernate.dialect.MySQLDialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy</referenceUrl> <driver>com.mysql.cj.jdbc.Driver</driver> </configuration>
4. 完善数据库连接配置
为MySQL URL添加时区参数,避免时区错误:
url=jdbc:mysql://localhost:3306/liquibasetest?serverTimezone=UTC
同时确认MySQL服务正常运行,liquibasetest数据库已创建,用户名密码正确。
5. 执行diff命令生成变更日志
运行Maven命令触发diff生成:
mvn liquibase:diff
内容的提问来源于stack exchange,提问作者Muhammed Aslam

