What are Flyway callbacks?
Callbacks are hooks that Flyway executes at specific points of the migration lifecycle.
They let you run custom logic:
- before / after migrations
- before validation
- after repair
- on success / on error
📌 Key idea:
“Callbacks allow you to react to migration lifecycle events.”
beforeMigrate: what exactly does it do?
beforeMigrate is executed:
- Right before
migratestarts - After validation
- Before any SQL migration is applied
Lifecycle order (simplified):
validate
→ beforeMigrate
→ migrate (V__ and R__)
→ afterMigrate
Important:
- If
beforeMigratefails → no migrations run - It acts like a gatekeeper
How callbacks are implemented
Flyway supports two main ways:
1️⃣ SQL-based callbacks (most common)
File naming convention:
beforeMigrate.sql
afterMigrate.sql
beforeValidate.sql
afterRepair.sql
Placed in:
- the same locations as migrations
- or configured callback locations
Example:
-- beforeMigrate.sql
SELECT current_database();
Typical use:
- sanity checks
- logging
- lightweight validations
2️⃣ Java-based callbacks (advanced / enterprise)
Implement Flyway’s callback interface:
public class BeforeMigrateCallback implements Callback {
@Override
public boolean supports(Event event, Context context) {
return event == Event.BEFORE_MIGRATE;
}
@Override
public void handle(Event event, Context context) {
// custom logic
}
}
Use cases:
- environment checks
- feature flags
- complex validations
- metrics / audit integration
📌 Interview note:
Java callbacks are evaluated inside the Flyway process, not the DB.
Typical real-world use cases for beforeMigrate
✅ Good uses
- Ensure correct schema / user / DB
- Check application version compatibility
- Validate prerequisites (extensions, roles, settings)
- Acquire advisory locks
- Emit audit / metrics events
Example (Postgres):
DO $$
BEGIN
IF current_user != 'migration_user' THEN
RAISE EXCEPTION 'Invalid DB user';
END IF;
END $$;
❌ Bad uses (red flags)
- Schema changes
- Data migrations
- Fixing broken history
- Business logic
Interview phrase:
“Callbacks should validate or observe, not mutate schema.”
Failure behavior (important)
If beforeMigrate:
- throws an error
- raises an exception
- returns failure
➡️ Flyway aborts migration immediately
No partial execution.
This makes callbacks ideal for fail-fast safety checks.
Relation to other Flyway features
| Feature | Purpose |
|---|---|
validateOnMigrate | Detect schema drift |
beforeMigrate | Enforce runtime safety |
| Versioned migrations | Apply irreversible changes |
| Repeatable migrations | Rebuild derived objects |
Good interview sentence:
“Validation checks history, callbacks check runtime conditions.”
Common pitfalls
❌ Putting business logic in callbacks
❌ Relying on callbacks for data correctness
❌ Assuming callbacks are transactional
❌ Making callbacks environment-specific without guards
Remember:
- Callbacks may or may not be transactional, depending on DB & event
- Don’t rely on rollback semantics
Interview-ready answer (perfect)
Short answer (2–3 sentences):
“Flyway callbacks like
beforeMigrateare lifecycle hooks executed at specific points during migration.beforeMigrateruns after validation and before any migrations are applied, and if it fails, migration is aborted. They’re typically used for safety checks, logging, or environment validation, not for schema or data changes.”