I have created Spring application. Pom xml is attached.
It has a config like this (below) and some db/migration/V1__init.sql for Flyway db migration tool.
It
I had the same issue.
I wanted my schema to be created by hibernate because of it's database independence. I already went through the trouble of figuring out a nice schema for my application in my jpa classes, I don't like repeating myself.
But I want some data initialization to be done in a versioned manner which flyway is good at.
Spring boot runs flyway migrations before hibernate. To change it I overrode the spring boot initializer to do nothing. Then I created a second initializer that runs after hibernate is done. All you need to do is add this configuration class:
import org.flywaydb.core.Flyway;
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
@Configuration
public class MigrationConfiguration {
/**
* Override default flyway initializer to do nothing
*/
@Bean
FlywayMigrationInitializer flywayInitializer(Flyway flyway) {
return new FlywayMigrationInitializer(flyway, (f) ->{} );
}
/**
* Create a second flyway initializer to run after jpa has created the schema
*/
@Bean
@DependsOn("entityManagerFactory")
FlywayMigrationInitializer delayedFlywayInitializer(Flyway flyway) {
return new FlywayMigrationInitializer(flyway, null);
}
}
That code needs java 8, If you have java 7 or earlier, replace (f)->{}
with an inner class that implements FlywayMigrationStrategy
Of course you can do this in xml just as easily.
Make sure to add this to your application.properties:
flyway.baselineOnMigrate = true
For more recent users that use Spring Boot +2.1 and as @mota commented into @user3707816's answer, you can use spring.flyway.enabled=false in application.properties and then create a new instance manually:
Flyway.configure().dataSource(dataSource)
.baselineOnMigrate(true)
.schemas(PG_DATABASE_SCHEMA)//optional, by default is public
.load().migrate();
All SQL migrations will start after Hibernate creates all the tables.
Spring Boot 2.2.2, Flyway 6.0.8
To disable boot for Flyway, insert into resources/application.properties:
spring.flyway.enabled=false
Create separate configuration for Flyway to make it load when Hibernate is ready:
@Configuration
public class FlywayConfiguration {
@Autowired
public FlywayConfiguration(DataSource dataSource) {
Flyway.configure().baselineOnMigrate(true).dataSource(dataSource).load().migrate();
}
}
Start your migration scripts from version 2:
resources/db.migration/V2__fill-tables.sql
V1 is used as a baseline, V1 file will be ignored.
may be because of the order
add on application.properties
flyway.out-of-order = true
or application.yml on spring
flyway:
out-of-order: true
This works for me with Spring Boot 2.3.1
1- you need to disable boot for Flyway, by insert into resources/application.properties:
spring.flyway.enabled = false
2- Start your migration scripts from version 2 as V1 is used as a baseline, V1 file will be ignored.
3- Make the @SpringBootApplication class implements CommandLineRunner interface (It is used to execute the code after the Spring Boot application started ). and it will be like this:
@SpringBootApplication
public class SpringBootApplication implements CommandLineRunner {
@Autowired
DataSource dataSource;
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
Flyway.configure().baselineOnMigrate(true).dataSource(dataSource).load().migrate();
}
}
This answer helped me
Spring Boot auto-configuration of Flyway ensures that database migrations have run before Hibernate is initialised. In other words, you can't rely on Flyway auto-configuration and use Flyway to populate tables created by Hinernate.
One solution is to fully embrace Flyway and use it to both create the tables and populate them. You can then switch off Hibernate's table creation (spring.jpa.hibernate.ddl-auto=none
). This approach is more robust as it will allow your database to evolve more easily. This is what I would recommend that you do.
Another solution is to disable auto-configuration of Flyway (flyway.enabled=false
) and to configure it your self. You can then configure Flyway to depend on Hibernate so that Hibernate has created the tables before Flyway tries to populate them.