Flyway and Spring Boot integration

imalik8088 picture imalik8088 · Mar 25, 2015 · Viewed 79.2k times · Source

I trying to integrate Flyway for migrations in a Spring Boot project with Hibernate and Spring JPA. I'm getting the following Exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flyway' 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: Found non-empty schema "PUBLIC" without metadata table! Use init() or set initOnMigrate to true to initialize the metadata table.

My pom.xml is looking like this:

<dependency>
  <groupId>org.flywaydb</groupId>
  <artifactId>flyway-core</artifactId>
  <version>3.2</version>
</dependency>

I'm using Hibernate and a config java file for postgres (dev stage) and h2 (local). The signatures are looking like this:

  @Bean(initMethod = "migrate")
  public Flyway flyway() {
    Flyway fly = new Flyway();
    fly.clean();
    fly.init();
    //flyway.setInitOnMigrate(true);
    fly.setSchemas("SBA_DIALOG");
    //flyway.setLocations("filesystem:src/main/resources/db/migration");
    fly.setDataSource(this.dataSource());
    fly.migrate();
    return fly;
  }
@Bean(name = "sbaEntityManagerFactory") @DependsOn("flyway")
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
...

I can't find anything about my problem described in this question. Can anybody help?

Answer

Patrick Cornelissen picture Patrick Cornelissen · Jul 11, 2015

Spring-Boot is capable on it's own to do this. Just add flyway as dependency to your project and spring-boot will pick it up. Flyway migration will start when the service starts up.

If you already have some tables in the database add:

spring.flyway.baselineOnMigrate = true 

in your property file to keep flyway calm when it discovers that some tables already exist. ;-)

Flyway should pick up your datasource. If you need for example another user or something like that for flyway, you can set these properties:

spring.flyway.url: jdbc:postgresql://${db.host}/${db.name}
spring.flyway.user: MYUSER
spring.flyway.password: MYPWD

(Of course add your values! You can use SPEL to reference other properties)

Update

One word of caution: If you use a clustered database you may encounter problems that multiple instances that are started at the same time try to perform the updates at the same time. This is a problem when the table locks don't work, which happened to me using a clustered mariaDB.