A versioned migration runner records which schema changes have been applied so application startup and deployment can reason about database state.
Spring Boot migrations: what a versioned runner must add to the SQL test
The current kit boundary
SchemaEvolutionContractTest calls JdbcTemplate.execute with ALTER TABLE statements and uses a fresh H2 database for each test. It checks the row behavior of expand, backfill and contract. A separate FlywayReceiptMigrationTest now executes three test-only versioned SQL files, records history and checks validation. SchemaEvolutionContractTest remains direct SQL; no runtime migration-on-startup wiring, target-engine test or repair policy is included.
Spring Boot can invoke a migration tool when the tool and its integration are present. A production rollout should pin migration scripts in version control, apply each version once, verify checksums and test the same scripts on the target database. The expansion fixture supplies a small SQL contract, not that deployment workflow.
Separate DDL from long data work
A backfill of millions of rows may exceed startup time and lock budgets. Keep it resumable and observable rather than hiding it in a startup hook. Gate contraction on measured completion and on old-writer retirement. Specify whether the migration runner or deployment pipeline owns execution so two rollout processes do not race ambiguously.
The next integration test should start from the previous released schema, apply versioned scripts, start old and new writers at the right stages, and inspect history plus row state after a failure. The test matrix names those cases.
Checked source
// The following names are a sketch; checked files are under db/relay-migration:
// V1__create_shipment_receipt.sql
// V2__add_nullable_tenant_id.sql
// V3__require_tenant_id.sqlVerification boundary
SchemaEvolutionContractTest checks direct H2 SQL. FlywayReceiptMigrationTest checks direct test-scoped Flyway execution and history; BootFlywayStartupTest checks a separate Boot context. The excerpt is shortened or a labelled design sketch; the kit contains the checked tests.
Costs and limits
Migration history and checksum validation are now checked in a separate H2 fixture. Target-database DDL, concurrent deployment, ReceiptApplication runtime integration and rollback remain untested. A separate non-web Boot startup test covers the local H2 migration path. The names above are a sketch; the actual test files have different names.
Common Mistakes
- Do not call direct JdbcTemplate DDL a versioned Flyway migration.
- Do not place an unbounded backfill in application startup.
- Do not contract before application versions and data are ready.
Read next
Spring database rollout: add a nullable column before changing every writer, Spring database backfill: assign historical rows before enforcing ownership, Spring database contract phase: reject old writers only after backfill, Spring schema rollout tests: check old and new writers at every phase.
Checked file and migration continuation
Continue with Flyway SQL migrations: record ordered schema changes against a real database, Flyway validation: detect a changed applied migration before another write.
