Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring Boot migrations: what a versioned runner must add to the SQL test

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A versioned migration runner records which schema changes have been applied so application startup and deployment can reason about database state.

Download Spring source kit

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

Java
// 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.sql

Verification 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.

spring
spring-boot
migration
Storage details