Flywayは、データベースのスキーマ変更をSQLファイルとして管理し、適用済みの履歴をデータベース自身に記録するマイグレーションツールです。Spring Bootは標準の自動設定に組み込んでいるため、依存関係を足してSQLを規約どおりに置けば、アプリケーション起動時にスキーマが最新化されます。この記事では導入手順と命名規則、spring.flyway.*の既定値を成果物から実測した値で整理し、Spring Boot 4系で何が変わったか、MongoDB対応が今どうなっているかまで踏み込みます。
まとめ
Spring Bootを使う場合、依存関係にFlywayのバージョンを書く必要はありません。spring-boot-dependenciesが管理しており、Spring Boot 4.1.0はFlyway 12.4.0、4.0.7は11.14.1、3.5.16は11.7.2を指します。Flyway本体の最新は13.3.0(2026年8月13日公開)で、1〜2メジャー分の差があります。
マイグレーションファイルはclasspath:db/migrationに置き、V1__説明.sqlの形式で命名します。適用履歴はflyway_schema_historyテーブルに残り、一度適用したファイルを書き換えるとチェックサム不一致で起動が止まります。
Spring Boot 4系では自動設定がspring-boot-flywayという独立モジュールへ切り出され、パッケージ名も変わりました。spring.flyway.*は81件から62件へ減っていますが、削除された21件は3.5.16の時点ですでに全件が非推奨扱いです。MongoDBについては、自動設定がJDBCのDataSourceを前提とするため自動設定経由の接続は成立せず、モジュールもNative Connector版のflyway-database-nc-mongodbへ差し替わっています。
Flywayが担うスキーマ変更の履歴管理
SQLファイルをバージョン管理下に置く仕組み
アプリケーションのコードはGitで管理されているのに、テーブル定義の変更だけ誰かが手作業でSQLを流している。この状態が事故を生みます。Flywayが解決するのはここです。ALTER TABLEやCREATE INDEXをバージョン番号付きのSQLファイルとしてリポジトリに置き、まだ適用していないものだけを順番に実行します。
開発元はイギリスのRedgate Softwareです。実行されるのは、書いたSQLそのもの。エンティティ定義からスキーマを推測する方式と違い、インデックスの種類、パーティション、制約名まで意図どおりに指定できます。実体はJavaライブラリで、13.3.0のJARマニフェストに記録されたJava-Versionは17。Java 17未満のランタイムでは最新版が動きません。Spring Boot 4.1.0が管理する12.4.0も同じくJava 17以上を要求します。
flyway_schema_historyが記録する適用状態
Flywayは初回実行時にflyway_schema_historyという管理テーブルを作成します。テーブル名はspring.flyway.tableで変更できますが、この名前が既定です。ここにバージョン番号、説明、実行したスクリプトのチェックサム、実行者、実行時刻、所要ミリ秒、成功可否が1行ずつ蓄積されていきます。
運用上の要はチェックサムです。適用済みファイルを後から編集すると、次回起動時にFlywayが記録済みの値と突き合わせ、不一致を検出します。この検証があるため、「一度マージしたマイグレーションは修正せず、新しい番号を足す」という規律が強制されます。検証を無効化するspring.flyway.validate-on-migrateをfalseにする運用は勧めません。不一致は、開発者の手元と本番でスキーマが分岐している警告そのものだからです。
Spring BootへのFlyway導入手順とバージョンの決まり方
依存関係の追加とspring-boot-dependenciesの管理版数
Mavenの場合、flyway-coreと、使用するデータベース向けのモジュールを追加します。バージョン指定は不要です。
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
</dependency>
データベース別モジュールの分離は一度に行われたわけではありません。MySQLはflyway-mysqlの初版が8.2.1で、Flyway 8.2系のうちに切り出されました。PostgreSQLとHSQLDBはflyway-database-postgresql/flyway-database-hsqldbの初版がともに10.0.0で、Flyway 10からの分離です。13.3.0のflyway-coreに残っているのはH2とSQLite程度なので、本番用のRDBMSでは追加モジュールが要ると考えて構いません。
実際に入るバージョンはspring-boot-dependenciesのflyway.versionで決まります。POMを直接確認すると、Spring Boot 4.1.0は12.4.0、4.0.7は11.14.1、3.5.16は11.7.2でした。Flyway本体の最新は13.3.0(2026年8月13日公開、13.0.0は同年7月20日)なので、Spring Bootの管理版は意図的に保守的です。13系の機能が要るなら、プロパティを上書きします。
<properties>
<flyway.version>13.3.0</flyway.version>
</properties>
ただし上書きは自己責任の領域です。Spring Bootの統合テストが検証しているのは管理版の組み合わせだけなので、上げるなら自プロジェクトのマイグレーションを一通り流すテストを用意します。使用中のSpring Bootがどの系列かはSpring Bootバージョン一覧とサポート期限で確認できます。
起動時に自動実行される条件とDataSourceの扱い
設定ファイルは、通常のDataSource設定があれば追加不要です。Flywayはアプリケーションと同じDataSourceを共有します。
spring.datasource.url=jdbc:postgresql://localhost:5432/appdb
spring.datasource.username=app
spring.datasource.password=secret
spring.flyway.enabled=true
自動設定が有効になる条件は、ソースコード上で3つに分かれています。DataSourceのBeanが存在する、spring.flyway.urlが設定されている、JdbcConnectionDetailsのBeanが存在する、のいずれか。マイグレーション専用の権限を持つ接続を使いたい場合はspring.flyway.urlとspring.flyway.userを別に指定すると、その接続だけがFlyway用に組み立てられます。
アプリ用DataSourceを流用する場合、起動直後のマイグレーション実行がコネクションプールを一時的に占有します。プールサイズが小さい構成で長いマイグレーションを流すと待ちが出るため、HikariCPの設定パラメータとプール設計も合わせて確認しておくと安全です。接続確立に備えるspring.flyway.connect-retriesは既定で0、間隔は120秒。コンテナ起動順が不定なCI環境ではこの値を3にすると、DBの起動待ちに最大6分の猶予ができます。
マイグレーションを実際に流すテストは、Testcontainersで本番と同じRDBMSを立てる方式が確実です。H2で通してもPostgreSQL固有のDDLは検証できません。接続設定の受け渡しは@ServiceConnectionによるTestcontainers接続設定の自動化で省力化できます。
マイグレーションファイルの命名規則と適用順序
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_index.sql |
| 拡張子 | sql-migration-suffixes | .sql | V2__add_index.sql |
| 文字エンコーディング | encoding | UTF-8 | — |
| バージョン番号の表記 | — | — | V1 / V1.1 / V1_1 |
Vのファイルはバージョン番号順に一度だけ実行され、履歴に記録されます。Rのほうはバージョン番号を持たず、中身が変わるたびに再実行。ビューやストアドプロシージャのように「常に最新の定義で置き換えたい」オブジェクトをRで書けば、差分DDLを書かずに済みます。なお、アンダースコアはドットと同じ区切りとして解釈されるため、V1_1とV1.1は同じバージョンです。
適用済みマイグレーションを打ち消すU接頭辞(Undo)もありますが、Spring Bootから設定する道はありません。対応するspring.flyway.undo-sql-migration-prefixはFlyway 10で削除済みで、Spring Boot 4系のプロパティ一覧にも存在しません。切り戻しは打ち消し用のマイグレーションを新しい番号で追加する形になります。
説明部分は日本語でも動きますが、避けたほうが無難です。flyway_schema_historyのdescription列に格納され、OSやDBの文字コード設定に依存するトラブルの入口になります。V3__add_soft_delete_flag.sqlのように英小文字とアンダースコアで揃えるのが実務上の落としどころです。
チェックサム不一致と番号追い越しで起きる起動失敗
本番で最も多い停止要因は、適用済みファイルの後編集です。エラーはFlywayValidateExceptionとして起動時に出ます。正しい対処は、編集を巻き戻して新しいバージョンのファイルを追加すること。それ以外の手はすべて履歴の整合性を犠牲にします。
もう1つ頻出するのが、ブランチ運用に起因する番号の追い越しです。機能ブランチAがV5、ブランチBがV6を作り、Bが先にマージされて本番にV6まで適用されたあと、AのV5がマージされる。このV5はIGNORED状態と判定され、Spring Bootの既定設定では警告ではなく検証エラーになります。flyway-core 13.3.0のソース上のメッセージは次の形です。
Detected resolved migration not applied to database: 5.
To ignore this migration, set -ignoreMigrationPatterns='*:ignored'.
To allow executing this migration, set -outOfOrder=true.
ここは立場をはっきりさせます。本番環境でspring.flyway.out-of-orderをtrueにするのは勧めません。適用順序が環境ごとに変わり、「開発環境では通ったのに本番で落ちる」を再現不能な形で作り込むためです。マージ時にリベースして番号を振り直す運用のほうが、面倒でも安全。番号衝突そのものを避けたいなら、日時ベースのバージョン(V20260817103000__add_index.sql)に切り替える手もあります。
spring.flyway.*の主要プロパティと既定値
起動時の挙動を決める16の既定値
Spring Boot 4.1.0のspring-boot-flywayモジュールに同梱された設定メタデータには、spring.flyway.で始まるプロパティが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 | トランザクション内実行 |
| ignore-migration-patterns | *:future | 無視するマイグレーション |
| target | latest | 適用の上限バージョン |
| lock-retry-count | 50 | ロック取得の再試行回数 |
| connect-retries | 0 | 接続リトライ回数 |
| fail-on-missing-locations | false | 探索先不在時の扱い |
| create-schemas | true | スキーマの自動作成 |
| placeholder-prefix | ${ | 置換プレースホルダ開始記号 |
いずれも接頭辞spring.flyway.を補って指定します。locationsの既定値はメタデータには出力されませんが、FlywayPropertiesのフィールド初期値としてclasspath:db/migrationが設定されています。
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設定の差分
自動設定クラスのパッケージ移動とモジュール分割
Spring Boot 4系では、自動設定が機能ごとの独立JARへ分割されました。3.5.16ではspring-boot-autoconfigureにorg.springframework.boot.autoconfigure.flyway.FlywayAutoConfigurationとして同梱されていたクラスが、4.1.0ではspring-boot-flywayというアーティファクトのorg.springframework.boot.flyway.autoconfigure.FlywayAutoConfigurationへ移っています。4.1.0のspring-boot-autoconfigure側にFlyway関連クラスは残っていません。
影響を受けるのは、自動設定クラスを名前で参照しているコードです。確実に落ちるのはspring.autoconfigure.excludeに旧FQCNを書いている場合で、除外対象が解決できず起動時に失敗します。@AutoConfigureBefore/@AutoConfigureAfterはクラスリテラルで参照していればコンパイルエラー、文字列で指定していれば順序指定が黙って効かなくなるという違いがあるため、後者は動作確認が要ります。移行前にまず旧パッケージ名を検索してください。
grep -rn "org.springframework.boot.autoconfigure.flyway" src/
ベンダー固有の拡張設定は、4.1.0のJAR内にOracle、PostgreSQL、SQL Serverの3種類だけが内部クラスとして存在します。spring.flyway.oracle.sqlplusやspring.flyway.postgresql.transactional-lockのような階層化されたプロパティが使えるのはこの3つだけ。他のDBはFlyway側の設定拡張を直接使う形になります。Spring Boot 4全体の変更点はSpring Boot 4の変更点と新機能の解説にまとめています。
削除された21プロパティと3.5系時点での状態
設定メタデータを3.5.16と4.1.0で突き合わせると、spring.flyway.*は81件から62件へ減っています。ここで重要なのは削除された事実そのものではありません。21件すべてが3.5.16の時点ですでに非推奨で、うち15件はlevel: errorとして登録されていたという点です。
| 削除された旧キー | 置き換え先 | 3.5.16での状態 |
|---|---|---|
| ignore-future / ignored / missing / pending-migrations | ignore-migration-patterns | error / Flyway 9.0で削除 |
| baseline-migration-prefix | なし | error / Flyway 9.0で削除 |
| license-key / cherry-pick / undo-sql-migration-prefix | なし | error / Flyway 10で削除 |
| vault-url / vault-token / vault-secrets | なし | error / OSS版7.12で削除 |
| error-handlers | なし | error / Flyway Teams専用 |
| sql-migration-suffix | sql-migration-suffixes | error |
| check-location | fail-on-missing-locations | error |
| oracle-kerberos-config-file | kerberos-config-file | error |
| oracle-sqlplus / -sqlplus-warn / -wallet-location / -kerberos-cache-file | oracle.* 配下へ | 非推奨 |
| sql-server-kerberos-login-file | sqlserver.kerberos-login-file | 非推奨 |
| clean-on-validation-error | なし | 非推奨 / Flyway 11.0で削除 |
この表が示すのは、「Spring Boot 4で新たに壊れる設定」がほとんど無いという事実です。clean-on-validation-errorを例に取ると、Flyway 10.18で非推奨・11.0で削除されており、3.5.16の管理版は11.7.2。つまり3.5系を使っている時点ですでに機能していません。4.1.0のメタデータには非推奨項目が1件も残っておらず、長年積み上がった別名と死んだキーが4系で一掃されたという構図になります。
移行時の実務対応は、旧キーが残っていないかの棚卸しです。Spring Bootは未知のプロパティをエラーにしないため、削除済みキーをapplication.propertiesに残したまま4系へ上げても起動は成功します。設定が黙って無視されるだけ。上の表の左列をgrepし、置き換え先がある6件はドット区切りの新表記へ書き換えてください。
なお追加されたのは2件のみで、spring.flyway.callback-locationsとspring.flyway.powershell-executableです。前者はコールバックスクリプトの探索先をlocationsと分離するもので、SQLコールバックを別ディレクトリで管理していたプロジェクトに効きます。
FlywayでMongoDBを扱う場合の実態と採否判断
Spring Bootの自動設定がMongoDBに接続できない理由
Flyway自体はMongoDBを扱えます。扱えないのは、Spring Bootの自動設定を経由する構成です。
根拠は自動設定のソースにあります。Flywayの設定を組み立てる内部クラスは@ConditionalOnClass(JdbcUtils.class)の配下に置かれ、接続の生成にはDataSourceBuilderとSimpleDriverDataSourceを使います。いずれもjavax.sql.DataSourceとJDBCドライバを前提とした部品です。Spring Bootが管理する62件のspring.flyway.*を数え上げても、MongoDB向けのキーは1件も含まれていません。
混乱しやすい点を切り分けておきます。jdbc:mongodb:というURL形式そのものは実在します。flyway-database-mongodb 12.0.0のクラスを開くと、jdbc:mongodb:、jdbc:mongodb+srv:、mongodb:、mongodb+srv:を受け付け、ドライバとしてcom.dbschema.MongoJdbcDriverを指定していることが確認できました。これはFlywayのCLIやAPIから使う形式で、Spring Bootの自動設定がこのドライバを解決する仕組みは持っていません。一方、ネット上に流通するspring.flyway.mongodb.uriのようなプロパティは、Spring BootにもFlywayにも存在しない設定です。書いても無視されるだけなので、原因の切り分けで時間を溶かさないでください。
Native Connector版への移行とmongosh依存
扱い方は移行の途中にあります。Maven Centralを見ると、JDBCラッパー方式のflyway-database-mongodbは12.0.0が最後の公開版です。同時期にflyway-core、flyway-database-postgresql、flyway-mysqlはいずれも13.3.0まで進んでいるので、このモジュールだけ版が取り残されている状態がはっきり読み取れます。
後継はNative Connector方式のflyway-database-nc-mongodbです。11.10.0から13.3.0まで51版が公開され、本体に追随しています。裏付けはSpring Bootの依存管理にも表れていて、3.5.16の管理対象はflyway-database-mongodbでしたが、4.1.0ではflyway-database-nc-mongodbへ差し替わり、旧モジュールは管理対象から外れました。同時にflyway-database-nc-couchbaseも追加されています。
Native Connectorは、JDBCラッパーを介さずネイティブドライバで接続する方式で、Flywayの全エディションで既定有効です。運用条件は次のとおり。マイグレーションファイルの拡張子は.jsか.jsonで、混在させられません。.jsを選ぶ場合はMongoshの実行ファイルが必要で、Dockerならredgate/flyway:13.3.0-mongo、-alpine-mongo、-azure-mongoのいずれかを使います。.jsマイグレーションはMongoshの制約でトランザクションを使えず、Dry-run機能も現時点では利用できません。公式のVerified VersionsはV5とV8です。
採否の判断を言い切ります。Spring BootアプリケーションのMongoDBスキーマ管理をFlywayでやるのは、勧めません。自動設定が使えない以上、Flywayを別プロセス(CLIまたはDockerイメージ)として起動し、mongoshの配置まで自前で管理することになるからです。RDBMSでFlywayを使っているチームが「同じツールで揃えたい」という理由だけで選ぶには、運用コストが釣り合いません。Spring Data MongoDBを使う構成なら、MongoDB専用ツールのMongock(mongock-bom 5.5.1が最新)を検討したほうが素直です。FlywayをMongoDBへ使う価値が出るのは、RDBMSとMongoDBの両方を含むデプロイパイプラインをRedgateのツールチェーンで一元管理している場合に限られます。
既存DBへの後付け導入と失敗時の復旧手順
baseline-on-migrateで運用中スキーマから始める
すでにテーブルが存在する本番データベースにFlywayを後付けするとき、そのまま起動すると「スキーマが空でない」旨のエラーで止まります。履歴テーブルの無いスキーマにオブジェクトが存在する状態を、Flywayが安全でないと判断するためです。
spring.flyway.baseline-on-migrate=true
spring.flyway.baseline-version=0
spring.flyway.baseline-description=existing schema
baseline-on-migrateをtrueにすると、Flywayは現在のスキーマをベースラインとして履歴テーブルに1行記録し、それより後のバージョンだけを適用します。ここで落とし穴になるのがbaseline-versionの既定値1。既定のままだとV1__のファイルがスキップされるため、既存のV1から適用したい場合は0を指定してください。
導入の型としては、現行スキーマをダンプしてV1__baseline.sqlに保存し、新規環境ではそれを起点に構築、既存環境ではbaseline-version=1で読み飛ばす形が扱いやすい構成です。新規と既存でスキーマ定義が1ファイルに揃うため、環境差分の調査が楽になります。
repairを使ってよい場面と使うべきでない場面
マイグレーションが途中で失敗すると、DDLをトランザクションで巻き戻せないデータベース(MySQL等)では履歴テーブルにsuccessがfalseの行が残ります。この状態では次回起動も止まります。復旧に使うのがrepair。失敗行の削除とチェックサムの再計算を行うコマンドです。Spring Bootの自動設定はマイグレーション実行時にrepairを呼ばないため、CLIかMavenプラグイン、あるいはFlywayMigrationStrategyのBeanを定義して明示的に呼び出す必要があります。
使い分けを明確にします。失敗行の除去に使うのは正当です。一方、本番のチェックサム不一致を消す目的で使うのは避けてください。不一致は、本番に適用されたSQLとリポジトリのSQLが違うという事実の通知です。repairで記録を書き換えれば警告は消えますが、実スキーマとコードの乖離は残ります。まず本番の実スキーマを確認し、差分を新しいマイグレーションで埋めるのが順序です。
JPAを併用する構成ではspring.jpa.hibernate.ddl-autoをvalidateかnoneにします。Hibernateがスキーマに手を入れると、Flywayの管理下にない変更が混入するためです。JPA周りの既定値の落とし穴はspring.jpa.open-in-viewの既定値と判断基準でも取り上げています。
よくある質問
Flywayの読み方と名前の意味は?
開発元Redgate Softwareの表記は英字のFlywayで、日本語では「フライウェイ」と読まれるのが一般的です。英単語のflywayは渡り鳥が季節移動に使う経路を指す語ですが、ツール名の由来を説明した公式の記述は、今回参照したドキュメント範囲では見当たりませんでした。読み方の揺れが問題になる場面は少ないため、社内資料でも英字のFlywayで統一しておくのが無難です。
spring.flyway.locationsの既定値は?複数指定できますか?
既定値はclasspath:db/migrationです。複数指定はカンマ区切りで可能で、classpath:db/migration,classpath:db/seedのように書きます。filesystem:接頭辞を付ければ、クラスパス外のディレクトリも指定可能。ただし指定したパスが存在しない場合、fail-on-missing-locationsが既定のfalseだとエラーにならず黙って無視されるため、マルチモジュール構成ではtrueにしておくと設定ミスに気付けます。
Spring Boot 4ではFlywayのどのバージョンが入りますか?
Spring Boot 4.1.0は12.4.0、4.0.7は11.14.1を管理値として指定しています。3.5.16は11.7.2でした。上書きするにはMavenならpom.xmlのpropertiesにflyway.versionを書き、Gradleならext["flyway.version"]を設定します。Flyway本体の最新13.3.0まで上げること自体は可能ですが、Spring Boot側が検証した組み合わせから外れるため、マイグレーションを流す統合テストとセットで行ってください。
FlywayとLiquibaseはどちらを選ぶべきですか?
SQLを直接書いてレビューしたいチームはFlyway、DB非依存の抽象記法でスキーマを定義しロールバックを標準機能として使いたいチームはLiquibaseが向きます。Spring Bootはどちらも自動設定を持ち、依存関係を入れるだけで起動時に実行されます。判断が付かない場合はFlywayを選んでください。マイグレーションがただのSQLファイルになるため、DBA・アプリ開発者・レビュアーの全員が読める形式に揃うという運用上の利点があります。
Spring Bootを介さずCLIやDockerでFlywayを実行するには?
スタンドアロン実行にはflyway-commandlineを使います。RedgateのダウンロードページからOS別のアーカイブを取得するか、Dockerイメージredgate/flywayを利用してください。CI/CDでアプリ起動と切り離してマイグレーションを流したい場合、この方式が適します。MongoDBへ.jsマイグレーションを流す場合は、Mongoshを含むredgate/flyway:13.3.0-mongo系のイメージを選びます。