Skip to content

Flyway

Databases & CachingDatabase/MigrationJava

What it is

Flyway is an open-source database migration tool for Java that allows developers to version, manage, and automate database schema changes. It supports SQL-based migrations as well as Java-based migrations for complex transformations.

Flyway allows defining migrations as SQL scripts or Java classes, tracks which migrations have been applied, and ensures the database is up-to-date. It supports multiple databases such as PostgreSQL, MySQL, Oracle, SQL Server, and SQLite.

Installation

Add dependency in pom.xml: <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>10.15.0</version> </dependency>

Getting started

The smallest useful thing you can do with it, and what each part means.

Basic Flyway configuration
import org.flywaydb.core.Flyway;

Flyway flyway = Flyway.configure()
    .dataSource("jdbc:postgresql://localhost:5432/mydb", "user", "password")
    .load();
flyway.migrate();
Configures Flyway with a PostgreSQL database and applies all pending migrations.
SQL-based migration
-- V1__create_users_table.sql
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);
Defines a SQL migration script named with Flyway's versioned naming convention (V1__).

Advanced usage

Where the library earns its place over a simpler alternative.

Java-based migration
import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import java.sql.Statement;

public class V2__Add_email_to_users extends BaseJavaMigration {
    @Override
    public void migrate(Context context) throws Exception {
        try (Statement stmt = context.getConnection().createStatement()) {
            stmt.execute("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
        }
    }
}
Defines a Java-based migration to add a column to the users table.
Undo migration
-- U2__remove_email_from_users.sql
ALTER TABLE users DROP COLUMN email;
Defines an undo migration script to revert a previous migration if needed.
Baseline an existing database
Flyway flyway = Flyway.configure()
    .dataSource("jdbc:mysql://localhost:3306/mydb", "user", "password")
    .baselineVersion("1")
    .baselineOnMigrate(true)
    .load();
flyway.baseline();
Sets a baseline for an existing database to start managing migrations without reapplying old scripts.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

FlywayException
Occurs if a migration fails or the database is in an inconsistent state. Inspect migration logs and fix the SQL/Java scripts.
ValidationException
Occurs when the applied migrations do not match the migration history. Use repair() cautiously to fix metadata.
SQLException
Occurs for database-level errors. Check connection settings, SQL syntax, and database compatibility.

Best practices

  • Use versioned migrations (V1__, V2__, ...) for schema changes to maintain order.
  • Keep SQL scripts small and atomic to reduce risks during migrations.
  • Store migration scripts in source control alongside application code.
  • Test migrations in a staging environment before production deployment.
  • Use Java-based migrations only when complex logic or conditional operations are required.

Background

Why it exists, and what it was reacting to.

Flyway was created to simplify database version control and continuous integration workflows. It enables developers to maintain consistent database schemas across environments, ensures smooth migrations, and integrates easily with Java applications and build tools. Flyway is widely used in enterprise applications, microservices, and automated deployment pipelines.