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
69 lines
4.2 KiB
Markdown
69 lines
4.2 KiB
Markdown
# 7. Why there is no undo
|
|
|
|
[← 6. Baselining an existing database](06-baselining-an-existing-database.md) · [Index](../README.md) · Next: [8. Concurrent startup and locking →](08-concurrent-startup-and-locking.md)
|
|
|
|
`Flyway` (the Community, Apache-2.0-licensed `flyway-core` artifact this module depends on) has a
|
|
public method called `undo()`. It compiles. Its Javadoc reads like every other command. Nothing
|
|
in its signature suggests it won't work — and that's exactly the trap:
|
|
[`FlywayUndoTest`](../src/test/java/com/ankurm/dbmigrations/flyway/FlywayUndoTest.java) migrates a
|
|
real database, then calls `flyway.undo()` on it, and the call throws at runtime:
|
|
|
|
```
|
|
flyway.undo() threw: org.flywaydb.core.internal.license.FlywayRedgateEditionRequiredException
|
|
message: Flyway Redgate Edition Required: undo is not supported by OSS Edition
|
|
Download Redgate Edition for free: https://rd.gt/3GGIXhh
|
|
```
|
|
|
|
(from [`docs/output/06-flyway-undo-teams-required.txt`](output/06-flyway-undo-teams-required.txt))
|
|
|
|
`undo` isn't a special case singled out for this article — it's one of a whole family of commands
|
|
that ship as compiled, callable, do-nothing stubs in the Community jar.
|
|
[`FlywayCommunityCommandSurfaceTest`](../src/test/java/com/ankurm/dbmigrations/flyway/FlywayCommunityCommandSurfaceTest.java)
|
|
doesn't take that on faith either: it opens the actual `flyway-core` jar on the test classpath at
|
|
runtime and lists every class under `org.flywaydb.core.internal.proprietaryStubs`, so this list is
|
|
read off the artifact Maven Central serves, not copied from a marketing page:
|
|
|
|
```
|
|
- auth
|
|
- check
|
|
- deploy
|
|
- diff
|
|
- difftext
|
|
- generate
|
|
- licensingconfigurationextensionstub.class
|
|
- model
|
|
- offlinepermitconfigurationextensionstub.class
|
|
- pattokenconfigurationextensionstub.class
|
|
- prepare
|
|
- undo
|
|
```
|
|
|
|
(from [`docs/output/07-flyway-proprietary-stub-commands.txt`](output/07-flyway-proprietary-stub-commands.txt))
|
|
|
|
<svg viewBox="0 0 700 160" xmlns="http://www.w3.org/2000/svg" font-family="monospace" font-size="13">
|
|
<rect x="20" y="20" width="300" height="120" rx="6" fill="#eef2ff" stroke="#4f46e5"/>
|
|
<text x="170" y="42" text-anchor="middle">flyway-core (Community, Apache-2.0)</text>
|
|
<text x="40" y="65" font-size="12">migrate() ✓ real</text>
|
|
<text x="40" y="85" font-size="12">baseline() ✓ real</text>
|
|
<text x="40" y="105" font-size="12">clean() ✓ real</text>
|
|
<text x="40" y="125" font-size="12">undo() — compiles, throws at runtime</text>
|
|
<path d="M330 125 L400 125" stroke="#334155" stroke-width="2" marker-end="url(#a4)"/>
|
|
<rect x="400" y="95" width="270" height="60" rx="6" fill="#fee2e2" stroke="#dc2626"/>
|
|
<text x="535" y="120" text-anchor="middle">FlywayRedgateEditionRequiredException</text>
|
|
<text x="535" y="138" text-anchor="middle" font-size="11">only at the moment undo() is called</text>
|
|
<defs><marker id="a4" markerWidth="8" markerHeight="8" refX="6" refY="4" orient="auto"><path d="M0,0 L8,4 L0,8 z" fill="#334155"/></marker></defs>
|
|
</svg>
|
|
|
|
The practical consequence: a compile-time check, a code review, or an IDE's autocomplete cannot
|
|
tell you that `undo()` needs a Redgate Teams or Enterprise license. Only calling it — or reading
|
|
the bytecode this test reads — does. For everyday rollback needs on the Community edition, the
|
|
honest options are the ones Flyway's own OSS command set actually supports: write and ship a new,
|
|
forward-only migration that reverses the change, or restore from a backup taken before the
|
|
migration ran. Both are less elegant than `flyway undo`, and both actually work on the free jar.
|
|
|
|
## Going deeper
|
|
|
|
- [Flyway editions comparison](https://www.red-gate.com/products/flyway/editions/) (`rel="nofollow"`) — the vendor's own breakdown of which commands need which tier.
|
|
- **This is not a licensing violation to work around.** The stub classes exist so a Community user who calls one of these APIs gets a clear runtime exception naming the required edition, rather than a `NoSuchMethodError` or a silent no-op — it's arguably the more honest of the two ways to gate a feature.
|
|
- Liquibase's own commercial/community split works differently — chapter [12](12-the-oss-license-service.md) verifies what actually happens on the Community jar's license-checking path, and it is not a stub-and-throw pattern at all.
|