Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring and Flyway - migrate before application context starts up

As the title suggests, I am looking for any means that could help me run Flyway migrations before Springs application context (persistence context to be precise) is loaded. The reason for that is I have few queries that run at the startup of the application. This leads to my tests failing as queries are being executed on database tables that do not yet exist. I am using H2 as my test database. Right now I am using only flyway core dependency:

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>6.5.0</version>
    <scope>test</scope>
</dependency>

and I have a single Flyway configuration class as follows:

@Configuration
class FlywayConfig {

    private static final String resourcePath = "classpath:flyway/migrations";
    private static final String sampleDataPath = "classpath:flyway/sample_data";

    @Bean
    Flyway flyway(@Value("${spring.datasource.url}") String dataSource,
                  @Value("${spring.datasource.username}") String username,
                  @Value("${spring.datasource.password}") String password) {


        FluentConfiguration fluentConfiguration = Flyway.configure().dataSource(dataSource, username, password);

        fluentConfiguration.locations(resourcePath, sampleDataPath);

        Flyway flyway = fluentConfiguration.load();

        return flyway;
    }
}

and the properties are defined in application.yml

spring:
  datasource:
    username: sa
    password: sa
    url: 'jdbc:h2:mem:testdb;Mode=Oracle;IGNORE_CATALOGS=TRUE;DB_CLOSE_DELAY=-1;'
    platform: h2
  h2:
    console:
      enabled: true
  jpa:
    show-sql: true

What I would like to achieve is that: 1. flyway does migration 2. Spring context loads up (in that particular order)

like image 712
Lisek Avatar asked Dec 21 '25 17:12

Lisek


1 Answers

I managed to be able to acomplish what I wanted by creating DataSource object manually in configuration file (not by Spring automatically from application.yml) and using @DependsOn on the DataSource object. This way I made sure that any possible database connection from the application context would be established once I do the migration in the Flyway bean (which btw I also tweaked). I was cleaning and migrating Flyway right before tests and now I have to do this while initalizing application context beans. Here is the code which worked for me:

@Configuration
class DatabaseConfig {

    private static final String resourcePath = "classpath:flyway/migrations";
    private static final String sampleDataPath = "classpath:flyway/sample_data";

    private static final String dataSourceUrl = "jdbc:h2:mem:testdb;Mode=Oracle;IGNORE_CATALOGS=TRUE;DB_CLOSE_DELAY=-1;";
    private static final String username = "sa";
    private static final String password = "sa";

    @Bean("flyway")
    public Flyway flyway() {

        FluentConfiguration fluentConfiguration = Flyway.configure().dataSource(dataSourceUrl, username, password);

        fluentConfiguration.locations(resourcePath, sampleDataPath);

        Flyway flyway = fluentConfiguration.load();

        flyway.clean();
        flyway.migrate();

        return flyway;
    }

    @DependsOn("flyway")
    @Bean
    public DataSource dataSource() {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.driverClassName("org.h2.Driver");
        dataSourceBuilder.url(dataSourceUrl);
        dataSourceBuilder.username(username);
        dataSourceBuilder.password(password);
        return dataSourceBuilder.build();
    }
}

and here is the application.yml file (I got rid of datasource related records):

spring:
  h2:
    console:
      enabled: true
  jpa:
    show-sql: true

flyway:
  enabled: false
like image 167
Lisek Avatar answered Dec 24 '25 10:12

Lisek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!