在休眠验证之前执行飞路迁移

Execute flyway migrations before hibernate validation

我有一个 spring 引导项目,它有多个模块。我希望它们都有单独的飞路配置。 例如:

@Component
@AutoConfigureAfter({ DataSourceAutoConfiguration.class,
    HibernateJpaAutoConfiguration.class })
@PropertySource("classpath:flyway.properties")
public class FlywayConfig {

  @PostConstruct
  public void startMigrations() {
    if(enabled) {
      Flyway flyway = new Flyway();
      flyway.setDataSource(dataSource);
      flyway.setSchemas(schema);
      flyway.setLocations(flywayLocation);
      flyway.setSqlMigrationPrefix(prefix);
      flyway.migrate();
    }
  }
}

问题与描述的问题相同。简而言之,hibernate 验证在 flyway 之前开始并抛出异常,因为 flyway 尚未创建表。

那种情况下的解决方案对我不起作用,因为我没有配置与休眠连接的 bean(我使用 spring 引导自动配置)。

我检查了 FlywayAutoConfiguration 并注意到有这样的东西:

@AutoConfigureAfter({ DataSourceAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class })

但这对我不起作用。

我不想为了添加 @DependsOn 而覆盖 spring 引导自动配置中的 bean(就像我上面发布的问题的解决方案一样)。我看不出为飞路配置创建 bean 的原因,因为它们需要在应用程序启动时执行一次。

我还使用了一个父模块,它将大部分模块合并在一起,但有时我想 exclude/include 在构建之前合并一个模块。如果我在必须在父模块中覆盖的 bean 上使用 @DependsOn 注释,这意味着我必须在每次构建之前更新代码。

所以,我的问题是:在执行hibernate验证之前,是否有另一种方法可以强制执行flyway?

我没有设法在不创建飞路 bean 的情况下找到执行飞路迁移的方法,但我确实设法避开了 @DependsOn 注释的使用。

这是我的飞行豆的样子:

上传器模块:

 @Configuration
  public class FlywayConfigUploader {

    @Bean("flywayUploader")
    public Flyway startMigrations() {
        Flyway flyway = new Flyway();
        flyway.setDataSource(dataSource);
        flyway.setSchemas(schema);
        flyway.setLocations(flywayLocation);
        flyway.setSqlMigrationPrefix(prefix);
        return flyway;
      }
    }

处理模块:

  @Configuration
  public class FlywayConfigProcessor {

    @Bean("flywayProcessor")
    public Flyway startMigrations() {
      Flyway flyway = new Flyway();
      flyway.setDataSource(dataSource);
      flyway.setSchemas(schema);
      flyway.setLocations(flywayLocation);
      flyway.setSqlMigrationPrefix(prefix);
      return flyway;
    }
  }

该项目目前有 10 个模块(因此有 10 个飞路配置)。以后模块数量可能会增加

我像 一样覆盖了 LocalContainerEntityManagerFactoryBean。 但是我没有使用 DependsOn 注释,而是将所有飞路 bean 添加为 LocalContainerEntityManagerFactoryBean bean 的依赖项。

  @Bean(name = "entityManagerFactory")
  public LocalContainerEntityManagerFactoryBean
  postgresEntityManagerFactory(EntityManagerFactoryBuilder builder, DataSource dataSource,
      List<Flyway> flywayBeans) {
    flywayBeans.forEach(el -> el.migrate());
    //Rest of the code from the method is not relevant for the question
    }

这样当用户决定排除或包含模块时不需要更新代码,因为每个模块都有一个 flyway bean,只有在构建中包含该模块时才会创建该 bean。

这样我们也可以控制flyway迁移的执行顺序。例如,我们可能有一个其他模块依赖的基础模块,因此必须首先执行从该模块的迁移。在那种情况下,我们可以将飞路配置包装在包装器 bean 中,该包装器 bean 将包含有关其顺序的信息。

public class FlywayWrapper {
private Flyway flywayConfig;
private Integer order;
}

在执行迁移之前,我们可以按顺序对它们进行排序。

flywayBeans.sort(Comparator.comparing(FlywayWrapper::getOrder));
flywayBeans.forEach(el -> el.getFlywayConfig().migrate());