How to Configure Liquibase for Database Version Management in ContiNew Admin

ContiNew Admin provides automatic database schema migration through Liquibase 4.27.0 integration with Spring Boot, requiring only the dependency presence and YAML configuration to execute change-sets on application startup.

The ContiNew Admin project leverages Liquibase to manage database evolution across development and production environments. This guide walks through the exact configuration files, properties, and SQL formatting conventions used in the continew-org/continew-admin repository to implement reliable, version-controlled database migrations.

Adding the Liquibase Dependency

Liquibase integration begins with the liquibase-core artifact declared in the server module's Maven configuration. In continew-server/pom.xml, the dependency is included without requiring an explicit starter spring component:

<dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-core</artifactId>
    <version>4.27.0</version>
</dependency>

Spring Boot's auto-configuration automatically instantiates a SpringLiquibase bean when this dependency is present on the classpath. No additional Java configuration or @Bean definitions are required to activate the migration framework.

Enabling Liquibase in Application Configuration

The global activation switch resides in the environment-specific YAML files. In continew-server/src/main/resources/config/application-dev.yml (and the corresponding application-prod.yml), Liquibase execution is controlled through the spring.liquibase namespace:

spring:
  liquibase:
    enabled: true
    change-log: classpath:/db/changelog/db.changelog-master.yaml
    # drop-first: false  # Use only in development environments

By default, spring.liquibase.enabled is set to true, ensuring migrations run automatically on every Spring context refresh. The change-log property points to the master YAML file that aggregates all individual migration scripts. For development scenarios requiring schema recreation, setting drop-first: true drops all existing database objects before applying the change-log.

Structuring Change-Log Files

Master Change-Log Organization

The entry point for all migrations is db.changelog-master.yaml located in src/main/resources/db/changelog/. This file uses the Liquibase include directive to reference database-specific scripts:

databaseChangeLog:
  - include:
      file: db/changelog/mysql/main_table.sql
  - include:
      file: db/changelog/mysql/main_data.sql
  - include:
      file: db/changelog/mysql/plugin/plugin_open.sql
  - include:
      file: db/changelog/mysql/plugin/plugin_tenant.sql
  # PostgreSQL alternatives (commented by default):

  # - include:

  #     file: db/changelog/postgresql/main_table.sql

The repository maintains separate directories for MySQL and PostgreSQL under src/main/resources/db/changelog/. Only the MySQL includes are active in the default configuration; switching to PostgreSQL requires uncommenting the corresponding include blocks and commenting out the MySQL references.

Database-Specific Script Locations

Individual SQL scripts follow a clear organizational pattern within their respective database folders:

  • main_table.sql – Contains DDL for core system tables
  • main_data.sql – Contains DML for seed data and initial records
  • plugin/ subdirectory – Houses schema definitions for optional modules like scheduling, tenant management, and code generation

Writing and Organizing Change-Sets

Liquibase tracks migrations using specially formatted SQL comments that identify each change-set. The repository follows a strict naming convention combining the author identifier and timestamp:

--liquibase formatted sql
--changeset continew:2024-01-create-user-table
CREATE TABLE IF NOT EXISTS sys_user (
    id BIGINT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
--rollback DROP TABLE sys_user;

Each change-set receives a unique identifier combining the id and author fields, along with an MD5 checksum stored in the DATABASECHANGELOG table. This guarantees idempotent executions—Liquibase skips previously run change-sets while applying new modifications in sequence.

Running Migrations

Automatic Execution

When the application starts, SpringLiquibase automatically executes pending migrations against the configured datasource. Liquibase creates two tracking tables in the target schema:

  • DATABASECHANGELOG – Records every applied change-set with checksums
  • DATABASECHANGELOGLOCK – Prevents concurrent migration execution

Manual Execution via Maven

For CI/CD pipelines or manual database updates outside application startup, use the Liquibase Maven plugin:

mvn liquibase:update -Dliquibase.changeLogFile=src/main/resources/db/changelog/db.changelog-master.yaml

This command applies all pending change-sets without requiring the full Spring Boot context to start.

Summary

  • Dependency: Add liquibase-core 4.27.0 to continew-server/pom.xml to enable auto-configuration
  • Configuration: Set spring.liquibase.enabled: true and specify the master change-log path in application-dev.yml or application-prod.yml
  • Master File: Use db.changelog-master.yaml to aggregate database-specific scripts via include directives
  • Multi-Database Support: Switch between MySQL and PostgreSQL by toggling commented sections in the master file
  • Change-Set Format: Prefix SQL files with --liquibase formatted sql and unique --changeset identifiers
  • Tracking: Liquibase automatically maintains the DATABASECHANGELOG table to ensure migrations run exactly once

Frequently Asked Questions

How do I disable Liquibase in a specific environment?

Set spring.liquibase.enabled: false in the corresponding YAML configuration file (e.g., application-test.yml). This prevents Liquibase from executing during application startup while keeping the dependency available for manual CLI usage.

Can I use Liquibase for multiple databases in the same project?

Yes. The ContiNew Admin structure supports this through the commented database-specific sections in db.changelog-master.yaml. Uncomment the PostgreSQL includes and comment out the MySQL includes to switch target databases, ensuring your datasource URL points to the correct database type.

What happens if a change-set fails during migration?

Liquibase marks the failed change-set in the DATABASECHANGELOG table with a failure state and rolls back the transaction (if your database supports transactional DDL). You must fix the SQL script, manually revert any partial changes, and clear the failed entry from the tracking table before restarting the application.

Where does Liquibase store migration history?

Liquibase creates the DATABASECHANGELOG table in the same schema as your application data. This table stores the ID, AUTHOR, FILENAME, DATEEXECUTED, and MD5SUM for every applied change-set, allowing the framework to determine which scripts have already run.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →