Mongock: ChangeUnits
|
This section documents schema/database evolution using version-controlled migration tools — Liquibase (relational/SQL), Mongock (MongoDB, Java-native) and Flamingock (Mongock’s successor, generalized to any external system) — as described by each tool’s own official documentation: liquibase.org and docs.liquibase.com for Liquibase, docs.mongock.io for Mongock, and docs.flamingock.io for Flamingock — which are the references these pages are written and verified against. This content was generated with the assistance of AI and should be verified against those official docs before being relied on in production. Mongock is now maintained under the Flamingock GitHub organization (github.com/flamingock/mongock), and Flamingock is positioned as its successor — see Coming from Mongock. Readers starting a new project should default to Flamingock unless they have a specific reason to stay on Mongock. This section’s bibliography lists the reference material consulted while preparing these pages. |
@ChangeUnit
Every Mongock migration is a class annotated @ChangeUnit, with four attributes:
| Attribute | Meaning |
|---|---|
|
Unique identifier — Mongock’s equivalent of a Liquibase changeset’s |
|
A string used to sort change units before execution — typically zero-padded ( |
|
Who wrote it, for the audit trail — purely informational, not part of identity the way Liquibase’s |
|
Optional — a version marker checked against the runner’s configured |
@Execution — Mandatory
Every @ChangeUnit needs exactly one @Execution method: the code that actually performs the migration. It can
accept any of Mongock’s supported dependency types as parameters (a MongoDatabase, a Spring Data
MongoTemplate, or an application-defined @Inject-able bean), depending on the driver in use
(Mongock: Getting Started):
@Execution
public void execution(MongoDatabase db) {
db.getCollection("person").updateMany(
Filters.exists("status", false),
Updates.set("status", "ACTIVE"));
}
@RollbackExecution — Highly Recommended
The inverse of @Execution, run if this migration needs to be undone. Unlike Liquibase, Mongock never generates
this automatically — it is always hand-written code, and the official reference marks it as highly
recommended rather than mandatory precisely because a change unit is materially riskier without one:
@RollbackExecution
public void rollback(MongoDatabase db) {
db.getCollection("person").updateMany(
Filters.eq("status", "ACTIVE"),
Updates.unset("status"));
}
A change unit with no @RollbackExecution can still run forward normally, but there is then no supported way to
undo it if it turns out to be wrong — see
Core Concepts' note on forward-only vs. reversible changes.
@BeforeExecution — Optional
An optional hook that runs before @Execution, outside of whatever transaction Mongock would otherwise wrap
the execution in (Mongock: Transactions &
Locking). It exists for operations MongoDB does not allow inside a multi-document transaction — most commonly
DDL-like operations such as creating a collection or an index, which MongoDB requires to run outside any active
transaction:
@BeforeExecution
public void beforeExecution(MongoDatabase db) {
db.createCollection("audit_log");
}
@Execution
public void execution(MongoDatabase db) {
db.getCollection("audit_log").insertOne(new Document("event", "initialized"));
}
A matching @RollbackBeforeExecution is available to undo whatever @BeforeExecution did, mirroring
@RollbackExecution for the main method.
Code-First vs. Declarative: The Contrast With Liquibase
The defining difference from Liquibase is that a Mongock change unit is Java code, compiled and reviewed like any other class, rather than a declarative file in a separate format. This means:
-
Full language power — loops, conditionals, calling into application services — is available inside a migration, where a declarative changelog would need Liquibase’s more limited built-in change types or an embedded script.
-
There is no DBA-reviewable, non-Java artifact — reviewing a Mongock migration means reading Java.
-
Ordering and the classpath-scanned "changelog" model follow the same rule as every code-based tool in this guide (Core Concepts' Changelog / Ordering section).
@BeforeExecution, @Execution and @RollbackExecution (with @RollbackBeforeExecution) can all live on the
same class — see the individual snippets above; there’s no requirement to split them across separate classes.
See the Migration / ChangeUnit reference for the full annotation and dependency-injection reference.