Flyway 3.x -> 5.xに上げた

Spring Boot2系にあげたときにやったことをまとめようと思います。(関連記事) 今回は、Flywayの話です。バージョンアップ後のSpring Bootのバージョンは2.0.9.RELEASEです。2.2対応はまたいつか書きます。

FlywayとSpring Boot

Flywayは、データベースマイグレーションライブラリです。 Spring Bootとの連携も簡単にできます。詳しくは、コチラを読んでください。

Spring Boot 1.5.22のFlywayのバージョンは3.2.1でしたが、Spring Boot 2.0.9では、5.0.7とメジャーバージョンが2つも上がりました。ちなみにSpring Boot 2.2.2では6.0.8になっています。

Flywayを3.x -> 5.xへ

まずカジュアルに3.x -> 5.xにあげてみましたが、マイグレーションが失敗しました...。

2019-09-11 03:43:15.152 ERROR --- Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Validate failed: Migration checksum mismatch for migration 1
-> Applied to database : 1750005324
-> Resolved locally    : -558371367
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:296)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:851)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175)
    at com.b1a9idps.sample.view.Application.main(Application.java:19)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:58)
Caused by: org.flywaydb.core.api.FlywayException: Validate failed: Migration checksum mismatch for migration 1

変更点

調べてみたら3 -> 44 -> 5で大きな変更が入っていました。

● 3 -> 4
チェックサム計算時に、改行コードを無視するようになりました。つまり、チェックサムの計算方法が4系から変更になりました。背景等は、[コチラ](https://flywaydb.org/blog/flyway-4.0)
● 4 -> 5
Flywayのメタデータを管理するテーブル名が `schema_version` から `flyway_schema_history` に変更になりました。詳しくは、[コチラ](https://github.com/flyway/flyway/issues/1848)

Flyway3 -> 5にするときの方法はちゃんとリリースノートに書いてありました。

Important note for users upgrading from Flyway 3.x: This release no longer supports a schema history table upgrade from Flyway 3.x. You must upgrade to Flyway 4.2.0 first before upgrading to Flyway 5.0.0.

Flyway 4系に上げる

Spring Boot 1.5.xのFlywayを4.2.0に上げます。

dependencies {
    compile "org.flywaydb:flyway-core:4.2.0"
}

起動します。

$ gradle bootRun

2019-09-11 03:43:14.467  INFO --- Upgrading metadata table `sample`.`schema_version` to the Flyway 4.0 format ...
2019-09-11 03:43:15.329  INFO --- Repairing metadata for version 1 (Description: CREATE TABLE SAMPLE DATA, Checksum: -558371367)  ...
2019-09-11 03:43:15.349  INFO --- Repairing metadata for version 2 (Description: MODIFY SAMPLE DATA LENGTH, Checksum: -1031537806)  ...
2019-09-11 03:43:15.370  INFO --- Repairing metadata for version 3 (Description: SAMPLE DATA ADD INDEX, Checksum: 194652164)  ...
2019-09-11 03:43:15.412  INFO --- Metadata table schema_version successfully upgraded to the Flyway 4.0 format.

初回起動時に、既存のメタデータを管理しているテーブルを自動的でアップデートしてくれました。

Flyway 5系に上げる

Spring Bootのバージョンを2.0.9.RELEASEあたりに上げて、設定ファイルのメタテーブルの名前を変更します。

spring.flyway.table=schema_version

Flywayが5.0.7になっていることを確認して起動すると特に問題なく起動できます。

おまけ

4 -> 5にするときにメタテーブルの名前を変更しなかった場合、6系からフォールバック機能がなくなるからテーブル名変更しろよって注意されます。

2019-09-25 23:05:33.882  WARN --- Could not find schema history table `sample`.`flyway_schema_history`, but found `test`.`schema_version` instead. You are seeing this message because Flyway changed its default for flyway.table in version 5.0.0 to flyway_schema_history and you are still relying on the old default (schema_version). Set flyway.table=schema_version in your configuration to fix this. This fallback mechanism will be removed in Flyway 6.0.0.

謝辞

カジュアルに3 -> 5に上げたときにエラーログ見てもさっぱり何もわかりませんでしたが、w氏の記事のおかげで助かりました。ありがとうございました。