JPA and FlywayDB Together with Spring Boot

If you’ve used Spring Data JPA or FlywayDB for SQL generation, the next step is to use JPA and FlywayDB together for robust DB creation and migration work.  JPA is great for entities.  FlywayDB is great for writing more complex SQL statements and data population.  If you have the bright idea like I did to combine the two to create a robust database management life-cycle, out of box you’ll run into problems fast – it just doesn’t work.

Spring Boot Life-cycle

When I started I added both dependencies to my build using the Spring Initalizr and figured everything would work right out of box.  I added @Entity to all models and created my migrations under db/migration like I would normally do and got excited when I went to do my first build.

IT FAILED.

The FlywayDB migrations tried to execute BEFORE the JPA entities generated their database tables.  This led all my migrations to fail as the tables did not exist.  Off to the internet!

Override Spring Boot Initializr for JPA and FlywayDB

A quick search brought me to this Stack Overflow question where people were encountering this same issue.  The best answer in my opinion was the overriding of the Spring Boot order as it is explicit and easy to understand.  By implementing a new Configuration to delay FlywayDB execution until after the EntityManagerFactory exists, means the migrations won’t execute until the JPA generation completes.

@Configuration
public class MigrationConfig {

    @Bean
    FlywayMigrationInitializer flywayInitializer(Flyway flyway) {
        return new FlywayMigrationInitializer(flyway, (f) ->{} );
    }

    @Bean
    @DependsOn("entityManagerFactory")
    FlywayMigrationInitializer delayedFlywayInitializer(Flyway flyway) {
        return new FlywayMigrationInitializer(flyway, null);
    }

}

By implementing the above class and executing the application again, the migrations fire off in expected order.  The configuration suppresses the first FlywayMigrationInitializer.

The Stack Overflow also states to add the following property to the properties file:

flyway.baselineOnMigrate=true

In Spring Boot 2.0 the property is:

spring.flyway.baselineOnMigrate=true

By implementing the above Configuration class and Spring Boot property, you can now have JPA and FlywayDB together in your applications!