Files
spring-boot-demo/db-migrations-flyway-liquibase/docs/09-liquibase-anatomy-of-an-update.md
T
asmhatreandClaude Sonnet 5 3908331431 Add db-migrations-flyway-liquibase: Flyway vs Liquibase migrations, rollbacks and baselines on Spring Boot 4.1
Companion code for the Flyway vs Liquibase article: checksum validation, out-of-order
and repeatable migrations, baselining an existing schema, Flyway Community's undo/diff/deploy
stubs, concurrent-startup locking for both tools, Liquibase changeset identity and rollback
(auto-generated vs explicit), a verified Liquibase 5.0.3 filename-caching defect, the new
OSS license service, the FSL license change, and running both tools against one database.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Q6XdRjtsp4862EM44T7i9a
2026-09-15 07:08:57 +00:00

4.1 KiB

9. Liquibase: anatomy of an update

← 8. Concurrent startup and locking · Index · Next: 10. Rollback: auto-generated vs explicit →

Liquibase's unit of change is a changeset inside a changelog — one YAML (or XML, or JSON, or SQL) document listing every change in order, rather than one file per change. This module's main changelog is db.changelog-master.yaml; LiquibaseHappyPathTest uses a small inline one — a createTable changeset, then an insert changeset — run through the classic Liquibase facade directly, with no Spring involved, so the mechanics are visible without an application context in the way.

databasechangelog:
ID               | AUTHOR | FILENAME    | ORDEREXECUTED | EXECTYPE
-----------------+--------+-------------+---------------+---------
1-create-account | ankurm | master.yaml | 1              | EXECUTED
2-seed-account   | ankurm | master.yaml | 2              | EXECUTED

account table:
ID | OWNER
---+------------------
1  | Katherine Johnson

(from docs/output/09-liquibase-happy-path.txt)

DATABASECHANGELOG is Liquibase's equivalent of flyway_schema_history, but the identity of a changeset is different in kind from Flyway's version numbers: it's the triple of id, author, and the changelog filename it was declared in. Two changesets with the same id in two different files are different changesets to Liquibase; the same id twice in the same file is a configuration error. There is no numeric ordering at all — order comes purely from position in the changelog, top to bottom.

master.yaml changeSet id: 1-create-account changeSet id: 2-seed-account DATABASECHANGELOG id=1-create-account, author=ankurm, filename=master.yaml → EXECUTED id=2-seed-account, author=ankurm, filename=master.yaml → EXECUTED

Going deeper

  • update() and the newer command-framework path. Liquibase 5's classic Liquibase.update(...) facade internally delegates to a CommandScope/UpdateCommandStep implementation rather than the older direct-execution path — visible in every stack trace in this module (chapter 11 has a full one). It doesn't change behaviour for straightforward changesets, but it's worth knowing when a stack trace looks unfamiliar next to older Liquibase tutorials.
  • Liquibase changelog structure (rel="nofollow") — the full list of supported changelog formats and the changeset identity rules referenced above.
  • Liquibase also supports preconditions and contexts/labels for conditionally running changesets — out of scope for this module, but the natural next thing to read once changesets and changelogs make sense.