Flywayは、データベースのスキーマ変更をSQLファイルとして管理し、適用済みの履歴をデータベース自身に記録するマイグレーションツールです。Spring Bootは自動設定を持っているので、依存関係を足してSQLを規約どおりに置けば、起動時にスキーマが最新化されます。ただしSpring Boot 4系では、3系と同じ依存関係の書き方だとFlywayが1本も実行されません。この記事ではSpring Boot 4.1.2、Flyway 12.4.0、H2 2.4.240、JDK 25の検証環境で確認した挙動をもとに、導入手順、命名規則、Callbacks、Javaマイグレーション、spring.flyway.*の既定値、MongoDB対応の現状までを整理します。
まとめ
Spring Boot 4系でFlywayを使うときは、flyway-coreではなくspring-boot-starter-flywayを追加します。自動設定がspring-boot-flywayという独立モジュールへ移ったため、flyway-coreだけを入れた構成では自動設定が読み込まれず、エラーも出ないままマイグレーションが走りません。PostgreSQLやMySQLを使う場合は、これに加えてデータベース別のモジュールが必要です。
Flywayのバージョンは書かなくて構いません。Spring Boot 4.1.2は12.4.0、4.0.9は11.14.1、3.5.16は11.7.2を管理しています。Flyway本体の最新は13.11.1(2026年10月21日公開)で、Spring Bootの管理版より1メジャー新しい状態です。
マイグレーションファイルはclasspath:db/migrationにV1__説明.sqlの形式で置きます。適用履歴はflyway_schema_historyテーブルに残り、適用済みファイルを書き換えるとチェックサム不一致で起動が止まります。マイグレーションの前後に処理を挟むCallbacksは、afterMigrate.sqlのようなSQLファイルか、Callbackを実装したBeanで書きます。afterMigrateは適用するものが無い起動でも毎回動くので、初期データの投入には向きません。
Flywayが担うスキーマ変更の履歴管理
SQLファイルをバージョン管理下に置く仕組み
アプリケーションのコードはGitで管理されているのに、テーブル定義の変更だけは誰かが手作業でSQLを流している。この状態が事故を生みます。FlywayはALTER TABLEやCREATE INDEXをバージョン番号付きのSQLファイルとしてリポジトリに置き、まだ適用していないものだけを番号順に実行します。
開発元はイギリスのRedgate Softwareです。実行されるのは書いたSQLそのものなので、エンティティ定義からスキーマを推測する方式と違い、インデックスの種類や制約名まで意図どおりに指定できます。実体はJavaライブラリで、公式のJava API要件はJDK 17以上です。同じページには「Flyway v14からJava 21が必須になる」と予告されているため、Java 17で運用しているプロジェクトは13系が上限になります。
flyway_schema_historyが記録する適用状態
Flywayは初回実行時にflyway_schema_historyという管理テーブルを作ります。名前はspring.flyway.tableで変えられます。ここにバージョン番号、説明、スクリプトのチェックサム、実行者、実行時刻、所要時間、成功可否が1行ずつ積み上がります。Javaで書いたマイグレーションはtype列がJDBC、SQLファイルはSQLとして記録されます。
運用の要はチェックサムです。適用済みファイルを後から編集すると、次回起動時にFlywayが記録済みの値と突き合わせて不一致を検出します。この検証があるので、「一度マージしたマイグレーションは直さず、新しい番号を足す」という規律が強制されます。検証を止めるspring.flyway.validate-on-migrate=falseは勧めません。不一致は、開発者の手元と本番でスキーマが分かれている警告そのものだからです。
Spring BootにFlywayを導入する手順
Spring Boot 4のspring-boot-starter-flyway依存設定
PostgreSQLに接続する場合のSpring Boot 4系の依存関係は次の3つです。spring-boot-starter-parentかBOMでSpring Bootの依存管理を適用していれば、バージョンは書きません。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-flyway</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
Gradleならimplementation("org.springframework.boot:spring-boot-starter-flyway")とimplementation("org.flywaydb:flyway-database-postgresql")に、runtimeOnly("org.postgresql:postgresql")を加えます。スターターはspring-boot-flyway(自動設定)、spring-boot-starter-jdbc、flyway-coreをまとめて引き込みます。
Spring Boot 3系の解説記事の多くはflyway-coreを足すだけの手順を載せています。これを4.1.2でそのまま書くと、ビルドも起動も通るのにマイグレーションは1本も実行されません。実際にflyway-core・spring-boot-starter-jdbc・H2だけの構成で起動したところ、Flywayのログは1行も出ず、flyway_schema_historyも作られませんでした。依存関係ツリーにもspring-boot-flywayが含まれていません。Spring Boot 4.0 Migration Guideにも、FlywayやLiquibaseを使っているならspring-boot-starter-flyway/spring-boot-starter-liquibaseへ置き換える必要があると書かれています。3系から上げるプロジェクトでは、真っ先にpom.xmlとbuild.gradleを確認してください。とりあえず起動させたいだけなら、全モジュールを含むspring-boot-starter-classicに切り替える逃げ道もありますが、移行ガイドは最終的にやめることを推奨しています。
データベース別モジュールが要るかどうかは接続先で決まります。Spring Bootの公式How-toによると、インメモリとファイルベースのデータベースはスターターだけで動き、それ以外はflyway-database-postgresqlやflyway-mysqlの追加が必要です。13.11.1のflyway-coreに入っているデータベース実装はH2とSQLiteだけなので、本番用のRDBMSでは追加モジュールが要ると考えてください。
管理されるFlywayのバージョンと上書きの判断
実際に入るFlywayのバージョンは、spring-boot-dependenciesのflyway.versionで決まります。Maven CentralのPOMを確認した結果は次のとおりです。
| Spring Boot | 管理するFlyway | 管理するLiquibase |
|---|---|---|
| 4.2.0-RC1 | 12.11.0 | 5.0.4 |
| 4.1.2 | 12.4.0 | 5.0.4 |
| 4.0.9 | 11.14.1 | 5.0.4 |
| 3.5.16 | 11.7.2 | 4.31.1 |
リリース候補の4.2.0-RC1でも管理版は12系にとどまっていて、13系はまだ入っていません。Flywayのリリースノートを見ると、13.0.0(2026年7月20日)の追加はOracleのIncludeOnlineIndexCreation対応、Flyway MCP server、jackson-databindの更新などで、Spring Bootから使う範囲で13系が必須になる機能は見当たりません。上げる理由が無ければ管理版のままにします。
どうしても13系の修正が要るなら、Mavenは<flyway.version>13.11.1</flyway.version>をpropertiesに、Gradleでio.spring.dependency-managementプラグインを使う場合は、Groovy DSLでext["flyway.version"] = "13.11.1"を設定します。Kotlin DSLではextra["flyway.version"] = "13.11.1"です。Gradle標準のBOMサポートでは、このプロパティによる上書きはできません。Spring Bootの統合テストが検証しているのは管理版の組み合わせだけなので、上書きするなら自プロジェクトの全マイグレーションを流すテストとセットにしてください。使用中のSpring Bootがどの系列で、いつまでサポートされるかはSpring Bootバージョン一覧とサポート期限(EOL)で確認できます。
起動時に自動実行される条件とDataSourceの扱い
通常のspring.datasource.*があれば、Flyway用の設定は要りません。Flywayはアプリケーションと同じDataSourceを使います。
spring.datasource.url=jdbc:postgresql://localhost:5432/appdb
spring.datasource.username=app
spring.datasource.password=secret
4.1.2のソースでは、自動設定が有効になる条件は3つのどれかです。DataSourceのBeanがある、spring.flyway.urlが設定されている、JdbcConnectionDetailsのBeanがある。DDLを流せる権限をアプリ用ユーザーに与えたくない場合は、spring.flyway.url・spring.flyway.user・spring.flyway.passwordを別に指定すると、その接続だけがFlyway用に組み立てられます。
アプリと同じプールを使う場合、起動直後のマイグレーションがコネクションを占有します。プールが小さい構成で長いマイグレーションを流すと待ちが出るため、HikariCPの既定値とSpring Bootでの設定も合わせて確認してください。接続の再試行回数spring.flyway.connect-retriesは既定で0です。コンテナの起動順が決まらない環境では3程度にしておくと、データベースの起動待ちで落ちにくくなります(再試行の間隔は最大120秒)。
マイグレーションファイルの命名規則と適用順序
VとRの接頭辞・区切り文字とバージョン番号
ファイルはsrc/main/resources/db/migrationに置きます。命名の構成要素は次のとおりです。
| 要素 | プロパティ | 既定値 | 例 |
|---|---|---|---|
| バージョン付き接頭辞 | sql-migration-prefix | V | V1__create_users.sql |
| 繰り返し実行接頭辞 | repeatable-sql-migration-prefix | R | R__user_view.sql |
| バージョンと説明の区切り | sql-migration-separator | __ | V2__add_email.sql |
| 拡張子 | sql-migration-suffixes | .sql | V2__add_email.sql |
| バージョン番号の表記 | — | — | V1 / V1.1 / V1_1 |
Vのファイルは番号順に一度だけ実行されます。Rはバージョン番号を持たず、中身が変わるたびに再実行されます。ビューやストアドプロシージャのように「常に最新の定義で置き換えたい」オブジェクトをRで書けば、差分DDLを書かずに済みます。実測でも、V1〜V3の適用が終わったあとにR__user_view.sqlが実行されました。区切りのアンダースコアはドットと同じ扱いなので、V1_1とV1.1は同じバージョンです。
適用済みの変更を打ち消すU接頭辞(Undo)もありますが、公式の機能比較ではTeamsとEnterpriseだけの機能で、無償のCommunityでは使えません。Spring Bootにも対応するプロパティはありません。切り戻しは、打ち消し用のマイグレーションを新しい番号で足す形になります。
説明部分に日本語を使うのは避けてください。description列に格納され、OSやデータベースの文字コード設定に左右されるトラブルの入口になります。V3__add_soft_delete_flag.sqlのように英小文字とアンダースコアで揃えるのが無難です。
チェックサム不一致と番号追い越しで起きる起動失敗
適用済みファイルの後編集は、起動時の検証を失敗させる原因になります。V1の末尾にコメントを1行足しただけで、4.1.2は起動時に次のエラーで止まりました。
Validate failed: Migrations have failed validation
Migration checksum mismatch for migration version 1
-> Applied to database : 1933001683
-> Resolved locally : 563834562
正しい対処は、編集を巻き戻して新しい番号のファイルを足すことです。それ以外の手は、どれも履歴の整合性を犠牲にします。
もう1つ頻出するのが、ブランチ運用に起因する番号の追い越しです。ブランチAがV4、ブランチBがV5を作り、Bが先にマージされて本番にV5まで適用されたあとでAのV4がマージされる。このV4は検証エラーになり、起動できません。実測したメッセージは次のとおりです。
Detected resolved migration not applied to database: 4.
To ignore this migration, set -ignoreMigrationPatterns='*:ignored'. To allow executing this migration, set -outOfOrder=true.
本番でspring.flyway.out-of-order=trueにするのは勧めません。適用順が環境ごとに変わり、「開発環境では通ったのに本番で落ちる」を再現できない形で作り込むからです。ignore-migration-patternsで無視させるのも、そのV4が本番に永久に適用されないという意味なので同じく危険です。マージ時にリベースして番号を振り直す運用のほうが、面倒でも安全です。番号の衝突そのものを減らしたいなら、V20261025103000__add_index.sqlのような日時ベースのバージョンに切り替える手もあります。
Callbacksによるマイグレーション前後の処理
SQLコールバックのafterMigrateとafterMigrateAppliedの違い
Callbacksは、migrateやvalidateといったFlywayの操作の前後に任意の処理を差し込む仕組みです。SQLで書く場合は、イベント名をそのままファイル名にしてdb/migrationに置きます。公式のCallbacksの説明どおり、afterMigrate.sqlはmigrate実行後に呼ばれます。afterMigrate__refresh_stats.sqlのように区切り文字の後ろへ説明を付けることもでき、同じイベントに複数のファイルを置けます。コールバックは履歴テーブルに記録されません。
どのイベントを選ぶかで結果が変わります。afterMigrate.sqlに1行を挿入するSQLを書いて2回起動したところ、2回目は「Schema “PUBLIC” is up to date. No migration necessary.」と適用ゼロだったにもかかわらず、行が2行に増えました。afterMigrateは適用の有無にかかわらず、migrateが成功するたびに動くためです。同じSQLをafterMigrateApplied.sqlに移すと、2回目の起動では実行されず1行のままでした。afterMigrateAppliedは、1本以上適用したときだけ動きます。
| イベント | 動くタイミング | 向く処理 |
|---|---|---|
| beforeMigrate | migrate開始前 | セッション設定 |
| afterEachMigrate | 1本適用するごと | 適用ログの出力 |
| afterMigrate | migrate成功のたび(適用0本でも) | 権限の再付与・統計更新 |
| afterMigrateApplied | 1本以上適用したとき | キャッシュ破棄・通知 |
| afterMigrateError | migrate失敗時 | 失敗の通知 |
何度実行しても結果が変わらない処理(GRANTや統計情報の更新)はafterMigrate、1本以上のマイグレーションが適用された実行ごとに行う処理はafterMigrateAppliedと使い分けます。マスターデータの投入はどちらにも置かず、Vのマイグレーションとして書いてください。コールバック用のSQLを別ディレクトリに分けたいときは、Spring Boot 4で追加されたspring.flyway.callback-locationsを使います。公式の説明によると、未設定ならマイグレーションのlocationsから探します。
JavaのCallbackのBean登録
SQLでは書けない処理は、org.flywaydb.core.api.callback.Callbackを実装したBeanにします。Spring BootはCallback型のBeanを集めてFlywayへ渡すので、@Componentを付けるだけで登録されます。複数ある場合の順序は@Orderで指定します。
@Component
class LoggingCallback implements Callback {
@Override
public boolean supports(Event event, Context context) {
return event == Event.AFTER_MIGRATE || event == Event.AFTER_EACH_MIGRATE;
}
@Override
public boolean canHandleInTransaction(Event event, Context context) {
return true;
}
@Override
public void handle(Event event, Context context) {
String v = context.getMigrationInfo() == null
? "-" : String.valueOf(context.getMigrationInfo().getVersion());
System.out.println("CALLBACK " + event.getId() + " version=" + v);
}
@Override
public String getCallbackName() {
return "logging";
}
}
4.1.2で起動すると、V1・V2・V3のそれぞれでafterEachMigrateが、最後にafterMigrateが1回出力されました。繰り返し実行のRに対するafterEachMigrateでは、バージョンがnullで渡ります。バージョン番号で分岐する処理を書くならnullの扱いを決めておいてください。13.11.1のソースにあるイベントは48種類で、clean・validate・baseline・repairにもそれぞれ前後のイベントがあります。
JavaマイグレーションとFlywayMigrationStrategy
JavaMigrationのBean登録
データの変換などSQLで書きにくい処理は、Javaのマイグレーションにできます。BaseJavaMigrationを継承し、クラス名をSQLと同じV3__seed_adminの形式にすると、その名前からバージョンと説明が決まります。Spring BootはJavaMigration型のBeanを自動でFlywayに登録するので、@Componentを付ければ他のBeanも注入できます。
@Component
class V3__seed_admin extends BaseJavaMigration {
@Override
public void migrate(Context context) throws Exception {
try (var st = context.getConnection().createStatement()) {
st.execute("insert into users(name) values ('admin')");
}
}
}
このクラスはV1・V2でusersテーブルを作った後に適用される前提です。ここでのContextはorg.flywaydb.core.api.migration.Context、親クラスはorg.flywaydb.core.api.migration.BaseJavaMigrationで、コールバックのContextとは別のクラスです。同じファイルに両方を書くとimportがぶつかります。Javaマイグレーションは既定ではチェックサムを持たないため、適用後のコード変更だけでは検証エラーになりません。変更を検知するには、getChecksum()を実装し、変更内容に応じたチェックサムを返します。便利に見えて、実際には「適用済みの内容が変わっても誰も気付かない」という意味です。SQLで書けるものはSQLで書いてください。
FlywayMigrationStrategyによる実行方法の変更
Spring Bootは起動時にFlyway.migrate()を呼ぶだけです。migrateの前にrepairを挟みたい、特定の条件では流したくない、といった制御はFlywayMigrationStrategyのBeanで差し替えます。
@Configuration
@Profile("repair")
class RepairStrategy {
@Bean
FlywayMigrationStrategy repairThenMigrate() {
return flyway -> {
flyway.repair();
flyway.migrate();
};
}
}
プロファイルを分けているのは、常時repairを挟む構成にしないためです。チェックサム不一致の状態でこのプロファイルを有効にして起動すると、repairが記録済みのチェックサムを書き換え、その後のvalidateが通りました。つまり不一致の警告は消えるが、本番に適用されたSQLが変わるわけではありません。使ってよい場面は後述の復旧手順で整理します。より細かくFlywayの設定をコードで変えたい場合はFlywayConfigurationCustomizerのBeanを使います。
spring.flyway.*の主要プロパティと既定値
起動時の挙動を決める既定値
Spring Boot 4.1.2のspring-boot-flywayに同梱された設定メタデータには、spring.flyway.で始まるプロパティが62件あります(4.2.0-RC1も同じ62件で、増減なし)。実務で触る頻度が高いものを並べます。
| プロパティ | 既定値 | 用途 |
|---|---|---|
| enabled | true | 自動実行の有効化 |
| locations | classpath:db/migration | スクリプト探索先 |
| table | flyway_schema_history | 履歴テーブル名 |
| baseline-on-migrate | false | 既存DBへの後付け導入 |
| baseline-version | 1 | ベースラインの版 |
| validate-on-migrate | true | チェックサム検証 |
| clean-disabled | true | clean操作の禁止 |
| out-of-order | false | 番号追い越しの許可 |
| execute-in-transaction | true | トランザクション内で実行 |
| group | false | 未適用分を1トランザクションに |
| ignore-migration-patterns | *:future | 検証で無視する対象 |
| target | latest | 適用する上限の版 |
| connect-retries | 0 | 接続の再試行回数 |
| fail-on-missing-locations | false | 探索先が無いときの扱い |
| callback-locations | (未設定) | コールバックの探索先 |
いずれも接頭辞spring.flyway.を補って指定します。locationsの既定値はメタデータには出ていませんが、FlywayPropertiesのフィールド初期値としてclasspath:db/migrationが入っています。公式How-toにあるとおり、classpath:db/migration/{vendor}と書けば、接続先の種類に応じてdb/migration/mysqlなどを読み分けます。
環境ごとに自動実行を止めたいときは、プロファイル別の設定ファイルでspring.flyway.enabled=falseにします。本番だけはCIのジョブからマイグレーションを流し、アプリ起動時には流さない、という分け方がこれでできます。
fail-on-missing-locationsとclean-disabledで分かれる事故の起き方
既定のまま放置すると危ういのがfail-on-missing-locationsです。falseなので、locationsのパスを打ち間違えてもFlywayは何も実行せずに正常起動します。マルチモジュール構成でパスがずれ、マイグレーションが1本も走っていないのにアプリが立ち上がる。この事故はCI用プロファイルでtrueにしておけば起動時に落とせます。
逆にclean-disabledがtrueなのは妥当な既定です。cleanはスキーマ内のオブジェクトを全削除する操作で、本番に誤爆すると戻せません。falseにするのは、ローカルで作り直すためのプロファイルだけにしてください。
Spring Boot 4移行で変わるFlyway設定の差分
自動設定クラスとFlywayMigrationStrategyのパッケージ移動
依存関係の次に効くのがパッケージ名の変更です。3.5.16ではspring-boot-autoconfigureのorg.springframework.boot.autoconfigure.flywayにあったクラスが、4系ではspring-boot-flywayのorg.springframework.boot.flyway.autoconfigureへ移りました。FlywayAutoConfigurationだけでなく、前の章で使ったFlywayMigrationStrategyやFlywayConfigurationCustomizer、@FlywayDataSourceも同じパッケージに入っています。これらを使っているコードはimportを直さないとコンパイルが通りません。
コンパイルで気付けない箇所もあります。spring.autoconfigure.excludeに旧FQCNを文字列で書いている場合や、@AutoConfigureAfter(name = "...")のように文字列で順序を指定している場合です。移行前に旧パッケージ名を検索してください。
grep -rn "org.springframework.boot.autoconfigure.flyway" src/ pom.xml build.gradle
ベンダー固有の設定は、4.1.2のJAR内にOracle・PostgreSQL・SQL Serverの3種類だけが内部クラスとしてあります。spring.flyway.postgresql.transactional-lockのような階層化されたプロパティが使えるのはこの3つです。Spring Boot 4全体の変更点はSpring Boot 4の変更点と新機能の解説にまとめています。
削除された21プロパティと3.5系時点での状態
設定メタデータを3.5.16と4系で比べると、spring.flyway.*は81件から62件に減っています。重要なのは削除そのものではありません。削除された21件は3.5.16の設定メタデータで全件が非推奨とされ、うち15件は削除済みを示すdeprecation.level=errorでした。これはIDE向けの情報で、指定すると必ず起動エラーになるという意味ではありません。
| 削除された旧キー | 置き換え先 | 3.5.16のメタデータ |
|---|---|---|
| ignore-future / ignored / missing / pending-migrations | ignore-migration-patterns | level=error |
| baseline-migration-prefix | なし | level=error |
| license-key / cherry-pick / undo-sql-migration-prefix | なし | level=error |
| vault-url / vault-token / vault-secrets | なし | level=error |
| error-handlers | なし | level=error |
| sql-migration-suffix | sql-migration-suffixes | level=error |
| check-location | fail-on-missing-locations | level=error |
| oracle-kerberos-config-file | kerberos-config-file | level=error |
| oracle-sqlplus ほか3件 | oracle.* 配下 | 非推奨 |
| sql-server-kerberos-login-file | sqlserver.kerberos-login-file | 非推奨 |
| clean-on-validation-error | なし | 非推奨 |
つまり、プロパティの面で「Spring Boot 4で新たに壊れる設定」はほとんどありません。ただしSpring Bootは未知のプロパティをエラーにしないため、削除済みキーを残したまま4系へ上げても起動は成功し、設定が黙って無視されます。左列のキーをgrepし、置き換え先があるものは新しい表記に書き換えてください。4系で追加されたのはcallback-locationsとpowershell-executableの2件です。
マイグレーションをテストで検証する方法
テスト専用マイグレーションによるデータ投入
テストでだけ使うデータは、src/test/resources/db/migrationに置きます。公式How-toの例はV9999__test-data.sqlで、本番用のマイグレーションのあとに、テスト実行時だけ適用されます。このファイルは実行可能JARにもコンテナイメージにも入りません。番号を大きく取るのは、本番側の番号と衝突させないためです。
本番と同じRDBMSでの実行とエンティティ照合
マイグレーションのテストは、本番と同じRDBMSをTestcontainersで立てて流すのが確実です。H2で通っても、PostgreSQL固有のDDLやMySQLの予約語は検証できません。接続設定の受け渡しは@ServiceConnectionによるTestcontainers接続設定の自動化で省けます。
JPAを併用する構成ではspring.jpa.hibernate.ddl-autoをvalidateにします。Flywayが作ったスキーマとエンティティの対応をHibernateが起動時に検査し、列の付け忘れを落としてくれます。updateのままだと、Flywayの管理外でHibernateがスキーマを書き換え、履歴に残らない変更が混ざります。JPAの既定値の落とし穴はspring.jpa.open-in-viewの既定値と判断基準でも取り上げています。
FlywayでMongoDBを扱う場合の実態と採否判断
Spring Bootの自動設定がMongoDBに接続できない理由
Flyway自体はMongoDBを扱えます。扱えないのは、Spring Bootの自動設定を経由する構成です。4.1.2のソースでは、Flywayの設定を組み立てる内部クラスが@ConditionalOnClass(JdbcUtils.class)の配下にあり、接続にはJDBCのDataSourceを使います。62件のspring.flyway.*にもMongoDB向けのキーはありません。
ネット上に出回っているspring.flyway.mongodb.uriのようなプロパティは、Spring BootにもFlywayにも存在しません。書いても無視されるだけなので、原因の切り分けで時間を使わないでください。MongoDB自体が業務に合うかどうかはMongoDBが向かない業務の判断基準で整理しています。
Native Connector版への移行とmongosh依存
Maven Centralでは、JDBCラッパー方式のflyway-database-mongodbは12.0.0(2026年1月)で更新が止まっています。後継はNative Connector方式のflyway-database-nc-mongodbで、Maven Centralには11.10.0以降の63版があり、最新は本体と同じ13.11.1です。Spring Bootの依存管理も、3.5.16のflyway-database-mongodbから4.1系ではflyway-database-nc-mongodbへ差し替わりました。
RedgateのMongoDBリファレンス(2026年10月21日更新)の運用条件は次のとおりです。マイグレーションの拡張子は.jsか.jsonで、1つのプロジェクトに混在させられません。.jsはmongoshが必要で、Dockerならredgate/flyway:13.11.1-mongo、-alpine-mongo、-azure-mongoのいずれかを使います。.jsのマイグレーションはmongoshの制約でトランザクションを使えず、Dry-runも使えません。検証済みバージョンはMongoDB V5とV9です。
Spring BootアプリケーションのMongoDBスキーマ管理をFlywayで行うのは勧めません。Spring Bootの標準自動設定では統合できず、Java APIによる独自の初期化処理か、CLI・Dockerによる別実行を組み込む必要があるためです。JavaScript形式のマイグレーションにはmongoshも必要です。RDBMSでFlywayを使っているので揃えたい、という理由だけでは運用コストが釣り合いません。Spring Data MongoDBの構成なら、MongoDB専用のMongock(mongock-bom 5.5.1、2025年3月以降更新なし)が候補になりますが、更新頻度は採用前に確認してください。FlywayをMongoDBに使う価値が出るのは、RDBMSとMongoDBを含むデプロイをRedgateのツールで一元管理している場合です。
既存DBへの後付け導入と失敗時の復旧手順
baseline-on-migrateによる既存スキーマへの導入
テーブルが既にある本番データベースにFlywayを後付けすると、履歴テーブルの無い空でないスキーマを安全でないと判断し、起動時に止まります。
spring.flyway.baseline-on-migrate=true
spring.flyway.baseline-version=1
spring.flyway.baseline-description=existing schema
baseline-on-migrateをtrueにすると、現在のスキーマをベースラインとして履歴に1行記録し、それより後のバージョンだけを適用します。扱いやすいのは、現行スキーマをダンプしてV1__baseline.sqlに保存し、新規環境ではそれを起点に作り、既存環境ではbaseline-version=1で読み飛ばす形です。新規と既存でスキーマ定義が1ファイルに揃うので、環境差分を調べやすくなります。逆に既存環境でもV1から流したいならbaseline-version=0を指定します。既存の空でないスキーマでは、既定値の1のままだとV1が読み飛ばされます。導入後はbaseline-on-migrate=falseに戻し、接続先を誤った場合に別の既存DBが自動でベースライン化されるのを防いでください。
repairを使ってよい場面と使うべきでない場面
PostgreSQLはDDLをトランザクションで巻き戻せますが、MySQLとMariaDBはできません。MySQL 8.4のマニュアルには、ROLLBACKしてもCREATE TABLEは取り消されないと書かれています。このためMySQLでマイグレーションが途中で落ちると、途中まで作られたオブジェクトが残り、履歴には失敗行が記録されて次回起動も止まります。1ファイルに複数のDDLを詰め込まず、1ファイル1変更にしておくと被害が小さく済みます。
復旧に使うのがrepairです。公式のrepairの説明では、失敗したマイグレーションを履歴から削除し、チェックサムなどを再調整しますが、残ったユーザーオブジェクトは手動で片付ける必要があると明記されています。Spring Bootの自動設定はrepairを呼ばないので、CLIかMavenプラグイン、あるいは前述のFlywayMigrationStrategyで明示的に呼びます。
失敗行を消すためにrepairを使うのは正当です。一方、本番のチェックサム不一致を消すためにrepairを使うのは避けてください。不一致は、本番に適用されたSQLとリポジトリのSQLが違うという通知です。repairで記録を書き換えれば警告は消えても、実スキーマとコードのずれは残ります。まず本番の実スキーマを確認し、差分を新しいマイグレーションで埋めるのが順序です。既存システムのデータベース移行やスキーマ設計の見直しを外部に相談したい場合は、データベース設計・移行支援も参考にしてください。
よくある質問
Flywayの読み方と意味は?
日本語では「フライウェイ」と読まれるのが一般的で、開発元Redgate Softwareの表記は英字のFlywayです。英単語のflywayは渡り鳥が季節移動に使う経路を指します。ツール名の由来を説明した公式の記述は見当たらないため、社内資料では英字のFlywayで統一しておくのが無難です。
spring.flyway.locationsの既定値は?複数指定できますか?
既定値はclasspath:db/migrationです。classpath:db/migration,filesystem:/opt/migrationのようにカンマ区切りで複数指定でき、filesystem:を付けるとクラスパス外のディレクトリも読めます。存在しないパスは既定では黙って無視されます。
Spring Boot 4ではFlywayのどのバージョンが入りますか?
Spring Boot 4.1.2は12.4.0、4.0.9は11.14.1、リリース候補の4.2.0-RC1は12.11.0を管理しています。13系へ上げる場合はflyway.versionを上書きします。
FlywayとLiquibaseはどちらを選ぶべきですか?
SQLを直接書いてレビューしたいチームはFlyway、データベース非依存の記法でスキーマを定義したいチームや、無償版でロールバックを使いたいチームはLiquibaseが向きます。Spring Boot 4ではどちらも専用スターター(spring-boot-starter-flyway/spring-boot-starter-liquibase)を入れると起動時に実行されます。迷うならFlywayを選んでください。マイグレーションがただのSQLファイルになり、DBA・開発者・レビュアーの全員が読める形に揃います。
Spring Bootを介さずCLIやDockerでFlywayを実行するには?
RedgateのダウンロードページからOS別のコマンドラインツールを取得するか、Dockerイメージredgate/flywayを使います。CI/CDでアプリの起動と切り離してマイグレーションを流したい場合はこの方式が向いていて、その際はアプリ側でspring.flyway.enabled=falseにして二重実行を防ぎます。MongoDBへ.jsのマイグレーションを流すなら、mongoshを含む-mongo系のイメージを選びます。