Spring Boot: Hibernate and Flyway boot order

前端 未结 6 636
一整个雨季
一整个雨季 2020-12-09 03:52

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

相关标签:
6条回答
  • 2020-12-09 04:05

    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
    
    0 讨论(0)
  • 2020-12-09 04:18

    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();
    
    0 讨论(0)
  • 2020-12-09 04:19

    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.

    0 讨论(0)
  • 2020-12-09 04:19

    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
    
    0 讨论(0)
  • 2020-12-09 04:23

    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

    0 讨论(0)
  • 2020-12-09 04:30

    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.

    0 讨论(0)
提交回复
热议问题