Changing execution order of flyway migration when you have multiple datasource

43 views Asked by At

I have two datasource that creates two schema and tables. Let's say first one is foo, and second one is bar.

  • DataSource config, and LocalContainerEntityManagerBean of foo defined in another library, which I'm using as a maven dependecy.
  • Bar configuration etc in my project.
  • Some migration scripts of bar, needs tables and data from foo.
  • But when I start my spring boot, spring first executes migration for bar, and I'm getting exception, because in sql it can't find foo.order for example, because bar worked first not foo.
  • I tried to add @DependsOn on Bar datasource and LocalContainerEntityManagerBean but it didn't change the execution order.

Below is from com.mythirdpary.FooConfig



@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    entityManagerFactoryRef = "fooEntityManagerFactory",
    transactionManagerRef = "fooTransactionManager",
)
public class FooDbConfig {

    public FooDbConfig() {
    }

    @Bean(
        name = {"fooDataSource"}
    )
    public DataSource fooDataSource(FooSettings settings) {
        try {
        SQLServerDataSource dataSource = new SQLServerDataSource();
        dataSource.setURL(settings.getDatasource().getUrl());
        dataSource.setUser(settings.getDatasource().getUsername());
        dataSource.setPassword(settings.getDatasource().getPassword());
        return dataSource;
    }

    @Bean(
        name = {"fooEntityManagerFactory"}
    )
    public LocalContainerEntityManagerFactoryBean fooEntityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("fooDataSource") DataSource fieldsDataSource, FooSettings settings) {
        if (settings.getDatasource().isMigrate()) {
            Flyway.configure().schemas(new String[]{"foo"}).dataSource(fieldsDataSource).locations(new String[]{"classpath:/db/migration/foo"}).load().migrate();
        }

        return builder.dataSource(fieldsDataSource).packages(new Class[]{FooModuleEntity.class}).persistenceUnit("FooModuleEntity").build();
    }

    @Bean(
        name = {"fooTransactionManager"}
    )
    public PlatformTransactionManager fooTransactionManager(@Qualifier("fooEntityManagerFactory") EntityManagerFactory fieldsEntityManagerFactory) {
        return new JpaTransactionManager(fieldsEntityManagerFactory);
    }
}

And below is from my Bar which is implemented in current project

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    entityManagerFactoryRef = "barEntityManagerFactory",
    transactionManagerRef = "barTransactionManager",
)
public class BarDbConfig {

@Bean(name = "barDataSource")
  @DependsOn({"fooEntityManagerFactory", "fooDataSource"})
  public DataSource barDataSource(BarSettings settings) throws JsonProcessingException {
    // almost same with foo
  }

  @Bean(name = "barEntityManagerFactory")
  @DependsOn({"fooEntityManagerFactory", "fooDataSource"})
  public LocalContainerEntityManagerFactoryBean entityManagerFactory(
          EntityManagerFactoryBuilder builder,
          @Qualifier("barDataSource") DataSource dataSource,
          BarSettings settings ) {

    if (settings.getDatasource().get("bar").isMigrate()) {
      Flyway.configure()
          .schemas("bar")
          .dataSource(dataSource)
          .locations("classpath:/db/migration/bar")
          .load()
          .migrate();
    }

    return builder
        .dataSource(dataSource)
        .// add neccessary packages
        .build();
  }

}

in application.properties if I set datasource.bar.migrate=false, I'm not getting any error, because foo flyway starts first, but when I set to true first bar flyway is starting, and I couldn't find a way to change this order, @DependsOn didn't worked.

0

There are 0 answers