LoginSignup
23
26

More than 5 years have passed since last update.

Spring Boot+Flyway とハマった点

Last updated at Posted at 2015-01-22

はじめに

PostgreSQLをJDBCで用いるSpring BootのWebアプリを作ろうとして、Flaywayを入れてみた。

  1. 結果、今まで動いていたテストケースが一斉に失敗するようになった。(H2Databaseが必要)

  2. PostgreSQLを使ってテストケースを実行するためにはContextinitializerの設定が必要だった。

以上2点のメモ。対象のWebアプリはSpring Boot + Apache Wicket (2)で作っていたのとほぼ同等のもの。

Flywayを使うためにやったこと

pom.xmlを変更する。flayway-coreは Spring Bootによってバージョンが自動的に設定される。

pom.xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>9.3-1102-jdbc41</version>
</dependency>
<dependency>
  <groupId>org.flywaydb</groupId>
  <artifactId>flyway-core</artifactId>
</dependency>

次にRDBの設定をSpring Boot に喰わせる。この場合はapplication.propertiesに設定した。

application.properties
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/foo
spring.datasource.username=bar
spring.datasource.password=baz

あとはsrc/main/resourcesに、db.migration パッケージを掘って、Flyway用のsqlを配置するだけ。ちょーかんたん。

v1_0__create-books.sql
-- For example...
create table books (
    isbn text primary key,
    book_name text not null,
);

これでSpring Bootを起動すると、RDB(PostgreSQL)のfooデータベースにbooksテーブルを生成してくれるし、SQLファイルをFlywayのルールに沿って増やしてあげるとマイグレーションしてくれる仕組みが整う。

ハマった点1:テストケースが動かない

「いやあ簡単に導入できた、良かった良かった」と気分良くテストケースを実行すると、テストケースが全て失敗し、真っ赤な世界に突入してしまった。

エラーログを追ってみると、いろいろ書いてあるんだけど、

Caused by: org. springframework. beans. factory. BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.

とか言われてるのが怪しいと思われる。

これをキーに検索してみると、Spring Boot - Cannot determine embedded database driver class for database type NONEに行き当たり、h2databaseをpom.xmlに追加したら解決したよ(意訳)的なことが書いてある。

pom.xml
<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <scope>test</scope>
</dependency>

H2databaseをpom.xmlに追加してみると、

INFO   --- [           main] o.f.c.i.dbsupport.DbSupportFactory       : Database: jdbc:h2:mem:testdb (H2 1.4)
INFO   --- [           main] o.f.core.internal.command.DbValidate     : Validated 1 migration (execution time 00:00.019s)
INFO   --- [           main] o.f.c.i.metadatatable.MetaDataTableImpl  : Creating Metadata table: "PUBLIC"."schema_version"
INFO   --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema "PUBLIC": << Empty Schema >>
INFO   --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1.0
INFO   --- [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 1 migration to schema "PUBLIC" (execution time 00:00.045s)

といった感じで、テストケースは(実行時にflywayが実行されて)正常終了するようになった。

Spring Bootでflywayを使うようなプロジェクトのテスト時には、標準で jdbc:h2:mem:testdbspring.datasource.url に設定されるようだ。(Spring力低くてあんまり自信ない)

ハマった点2:PostgreSQLでテストしたいときはどうするの?

折角なのでH2databaseではなく、テスト時もPostgreSQLでFlywayを実行して貰いたいなーとReference Guideを検索してみたら、ConfigFileApplicationContextInitializer使えばいいのよと書いてあった。

テストケースクラスのContextConfigrationでConfigFileApplicationContextInitializer.classを指定してあげると、テストの実行時にapplication.propertiesを読み込んでくれるらしい。

というわけで、テストケースクラスの

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { WebInitializer.class, WicketApplication.class })
public class FooTest {
...

のアノテーションの設定を

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
  classes = { WebInitializer.class, WicketApplication.class },
  initializers = ConfigFileApplicationContextInitializer.class)
public class FooTest {
...

と変更した。またpom.xmlのh2databaseのdependencyは取り除いた。実行してみると、

INFO   --- [           main] o.f.c.i.dbsupport.DbSupportFactory       : Database: jdbc:postgresql://localhost:5432/foo (PostgreSQL 9.4)
INFO   --- [           main] o.f.core.internal.command.DbValidate     : Validated 1 migration (execution time 00:00.023s)
INFO   --- [           main] o.f.c.i.metadatatable.MetaDataTableImpl  : Creating Metadata table: "public"."schema_version"
INFO   --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema "public": << Empty Schema >>
INFO   --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema "public" to version 1.0
INFO   --- [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 1 migration to schema "public" (execution time 00:00.064s).

無事、テスト時にもapplication.propertiesの値を読み込んで、PostgreSQLが利用されるようになった。

23
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
26