Spring Boot 在休眠验证之前执行flyway迁移

arknldoa  于 5个月前  发布在  Spring
关注(0)|答案(2)|浏览(66)

我有一个Spring的 Boot 项目,有多个模块。我想他们都有单独的飞行配置。例如:

@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();
    }
  }
}

字符串
这个问题与here描述的问题相同。简而言之,hibernate验证在flyway之前开始并抛出异常,因为flyway还没有创建表。
这种情况下的解决方案对我不起作用,因为我没有与hibernate连接的bean的配置(我使用spring Boot AutoConfiguration)。
我检查了FlywayAutoConfiguration,注意到有这样的东西:

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


但这对我来说不起作用。
我不想为了添加@DependsOn而覆盖spring Boot AutoConfiguration中的bean(就像我上面发布的问题的解决方案一样)。我不认为有理由为flyway配置创建bean,因为它们需要在应用程序启动时执行一次。
我也使用父模块,它将大多数模块合并在一起,但有时我想在构建之前排除/包含一个模块。如果我在父模块中必须覆盖的bean上使用@DependsOn注解,这意味着我必须在每次构建之前更新代码。
所以,我的问题是:有没有其他方法可以在执行hibernate验证之前强制执行flyway?

qfe3c7zg

qfe3c7zg1#

我没有设法找到一种方法来执行flyway迁移而不创建flyway bean,但我确实设法避免了@DependsOn注解的使用。
以下是我的Flyway Bean的样子:
扩展器模块:

@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个这样的飞行路线配置)。模块的数量可能会在未来增加。
我像在this answer中一样覆盖了LocalContainerEntityManagerFactoryBean,但我没有使用DependsOn注解,而是将所有的flyway 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迁移的执行顺序。例如,我们可能有一个其他模块依赖的基本模块,因此必须首先执行从该模块的迁移。在这种情况下,我们可以将flyway配置 Package 在一个 Package 器bean中,该 Package 器bean将包含有关其顺序的信息。

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


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

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

hsgswve4

hsgswve42#

我遇到了同样的问题,遇到了这个答案,开始输入@DependsOn,看到有一个新的注解称为@ DependsOnDatabase(自Sping Boot 2.5.0起可用)。
这解决了这个问题,而无需我提到任何依赖Flyway。

相关问题