32
votes

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?

2
Spring Boot already supports flyway the only thing you need is add flyway as a dependency... I suggest a read of the manual and for the configuration properties. For me it looks like you are using boot and try very hard to work around it (explicitly configuring everything for instance).M. Deinum
quite strange: spring boot should not start flyway autoconfiguration if you configure flyway for yourself (question is if it is necessary). however error comes from boot autoconfiguration. however try to add flyway.initOnMigrate= true to your application.properties and remove your own flyway initialization :)sodik
@sodik Actually I've flyway in classpath (3.2.1) and it does not work. What may be the problem?Opal
for me the issue was the flyway and spring version missmatchtibbus

2 Answers

55
votes

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.

7
votes

For any one who want to solve it in java code you can use :

fly.setBaselineOnMigrate(true);

Edit(22-09-2020)

another solution also is :

spring:
  flyway:
    baselineOnMigrate: true
    validateOnMigrate: false