Spring Boot集成Liquibase遇校验和错误及幽灵变更日志问题
问题描述
我正在开发Spring Boot应用,用Liquibase做数据库初始化,一开始运行正常。但修改了变更日志后,删除数据库再用Maven构建没问题,启动应用却出现校验和错误。
试过再次删库、用Maven插件清校验和、同步,都没用。更奇怪的是,就算删掉变更日志里的内容,启动应用还是会用最新的变更构建数据库。后来改了变更日志文件名和变更集名称,出现了以下错误:
liquibase.exception.MigrationFailedException: Migration failed for changeset classpath:db_changelog.sqlite.sql::1::Example:
Reason: liquibase.exception.DatabaseException: [SQLITE_ERROR] SQL error or missing database (table example_table already exists) [Failed SQL: (1)
想知道Liquibase到底是从哪里读取这些表结构的?
我的配置
Liquibase Bean配置(已排除自动配置,强制使用此配置)
@Bean public SpringLiquibase liquibase() { SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setChangeLog("classpath:db_changelog.sqlite.sql"); liquibase.setDataSource(dataSource()); return liquibase; }
Maven插件配置
<plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>${liquibase.version}</version> <configuration> <driver>org.sqlite.JDBC</driver> <changeLogFile>./src/main/resources/db_changelog.sqlite.sql</changeLogFile> <url>jdbc:sqlite:../database.db</url> <outputChangeLogFile>generatedChangelog.sqlite.sql</outputChangeLogFile> </configuration> </plugin>
问题解答
Liquibase读取表结构的来源
指定的主变更日志文件:你配置的
db_changelog.sqlite.sql是核心来源,但你遇到的异常,大概率和以下额外路径有关:- 生成的变更日志文件:你的Maven插件配置里指定了
outputChangeLogFile为generatedChangelog.sqlite.sql,如果之前执行过liquibase:generateChangeLog这类命令,这个生成的文件会被Liquibase自动识别加载(Spring Boot环境下,Liquibase会扫描classpath下所有符合规则的变更日志)。就算你清空了主变更日志,这个文件里可能还保留着旧的表结构定义。 - Spring Boot自动扫描的其他文件:哪怕你排除了自动配置,Spring Boot仍可能扫描classpath下的
db/changelog目录、或者其他命名符合默认规则的变更日志文件,如果有残留的旧文件,也会被加载。
- 生成的变更日志文件:你的Maven插件配置里指定了
数据库元数据表(本次排除):正常情况下Liquibase会创建
databasechangelog和databasechangeloglock记录已执行的变更,但你已经删除过数据库,所以这次问题不是源于这里。
解决当前问题的具体步骤
- 删除生成的变更日志:找到
generatedChangelog.sqlite.sql文件并彻底删除,这个是你Maven插件指定的输出文件,很大概率存着旧表结构。 - 清理构建目录:执行
mvn clean,确保target目录下的旧资源被清空,避免打包时带入旧的变更日志。 - 核对数据库路径:你的Maven插件配置的数据库路径是
../database.db,但Spring Boot应用运行时可能在其他路径(比如target目录)创建了数据库文件,你手动删除的可能不是应用实际连接的那个。检查Spring Boot的数据源配置,找到数据库文件的真实位置并删除。 - 排查classpath下的其他变更日志:确认src/main/resources下没有其他
db_changelog*.sql、liquibase*.xml之类的文件,避免Liquibase加载额外的变更内容。
内容的提问来源于stack exchange,提问作者Kerllicky
相关产品推荐
相关产品推荐

