Liquibase generateChangeLog生成空变更日志文件的原因排查
Let's break down why your generateChangeLog command is only producing a header without any schema content, and fix it step by step:
Core Issue: Your H2 Database Instance Is Empty
The most likely culprit here is that the H2 database Liquibase is connecting to has no tables or schema objects at all. This happens frequently with H2's in-memory mode, but can also affect file-based instances:
- For in-memory H2 (
mem:testdb): Each new connection creates a fresh, empty database by default. If you created tables in a separate session (like a console or your app), that session closing would wipe the in-memory instance completely. - For file-based H2: Either the file path is incorrect, the file doesn't contain any tables, or Liquibase doesn't have read access to it.
Step-by-Step Fixes
1. Fix In-Memory H2 Connection Parameters
To keep your in-memory database alive across sessions, add these critical parameters to your JDBC URL:
liquibase --driver=org.h2.Driver --classpath=./h2-1.4.199.jar --changeLogFile=db.schema.sql --url="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE" --username=sa --password= --logLevel=debug generateChangeLog
DB_CLOSE_DELAY=-1: Prevents H2 from closing the database when the last connection is closed.DB_CLOSE_ON_EXIT=FALSE: Stops H2 from shutting down the database when the JVM exits.
2. Verify Your Database Actually Contains Tables
Before running Liquibase, confirm the database has schema objects:
- Open the H2 Console (run
java -jar h2-1.4.199.jar) and connect using the exact same JDBC URL you're using for Liquibase. - Check if tables exist in the
PUBLICschema (or your custom schema). If not, create a test table manually (e.g.,CREATE TABLE test (id INT);) and re-run thegenerateChangeLogcommand. If it picks up the test table, your original issue was an empty database.
3. Validate File-Based H2 Setup (If Using)
If you switched to a file-based H2:
- Double-check the JDBC URL path (e.g.,
jdbc:h2:./my-db-fileuses a relative path; use an absolute path likejdbc:h2:/home/user/data/my-dbfor clarity). - Ensure the H2 database file (
*.mv.db) exists in the specified location and has read permissions for the user running Liquibase.
4. Check Liquibase-H2 Version Compatibility
Your H2 version is 1.4.199—make sure you're using a Liquibase version that supports it. Older Liquibase versions (pre-4.x) may have compatibility issues with newer H2 releases. Try upgrading to Liquibase 4.10+ if you're on an older version.
5. Explicitly Specify Schema (If Needed)
If your tables are in a non-default schema (not PUBLIC), add the --includeSchema parameter to your command:
liquibase --driver=org.h2.Driver --classpath=./h2-1.4.199.jar --changeLogFile=db.schema.sql --url="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" --username=sa --password= --includeSchema=your_schema_name --logLevel=debug generateChangeLog
Quick Troubleshooting Checklist
- Connected to the exact same H2 instance that contains your tables (use H2 Console to confirm)
- Added
DB_CLOSE_DELAY=-1andDB_CLOSE_ON_EXIT=FALSEfor in-memory H2 - Verified Liquibase version is compatible with H2 1.4.199
- Tested with a manually created test table to rule out Liquibase functionality issues
内容的提问来源于stack exchange,提问作者user3475366

