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

arknldoa  于 2024-01-06  发布在  Spring
关注(0)|答案(2)|浏览(169)

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

  1. @Component
  2. @AutoConfigureAfter({ DataSourceAutoConfiguration.class,
  3. HibernateJpaAutoConfiguration.class })
  4. @PropertySource("classpath:flyway.properties")
  5. public class FlywayConfig {
  6. @PostConstruct
  7. public void startMigrations() {
  8. if(enabled) {
  9. Flyway flyway = new Flyway();
  10. flyway.setDataSource(dataSource);
  11. flyway.setSchemas(schema);
  12. flyway.setLocations(flywayLocation);
  13. flyway.setSqlMigrationPrefix(prefix);
  14. flyway.migrate();
  15. }
  16. }
  17. }

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

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


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

qfe3c7zg

qfe3c7zg1#

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

  1. @Configuration
  2. public class FlywayConfigUploader {
  3. @Bean("flywayUploader")
  4. public Flyway startMigrations() {
  5. Flyway flyway = new Flyway();
  6. flyway.setDataSource(dataSource);
  7. flyway.setSchemas(schema);
  8. flyway.setLocations(flywayLocation);
  9. flyway.setSqlMigrationPrefix(prefix);
  10. return flyway;
  11. }
  12. }

字符串
处理模块:

  1. @Configuration
  2. public class FlywayConfigProcessor {
  3. @Bean("flywayProcessor")
  4. public Flyway startMigrations() {
  5. Flyway flyway = new Flyway();
  6. flyway.setDataSource(dataSource);
  7. flyway.setSchemas(schema);
  8. flyway.setLocations(flywayLocation);
  9. flyway.setSqlMigrationPrefix(prefix);
  10. return flyway;
  11. }
  12. }


该项目目前有10个模块(因此有10个这样的飞行路线配置)。模块的数量可能会在未来增加。
我像在this answer中一样覆盖了LocalContainerEntityManagerFactoryBean,但我没有使用DependsOn注解,而是将所有的flyway bean作为依赖项添加到LocalContainerEntityManagerFactoryBean bean。

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


这样,当用户决定排除或包含模块时,就不需要更新代码,因为每个模块都有一个flyway bean,只有在构建中包含该模块时才会创建该bean。
通过这种方式,我们还可以控制flyway迁移的执行顺序。例如,我们可能有一个其他模块依赖的基本模块,因此必须首先执行从该模块的迁移。在这种情况下,我们可以将flyway配置 Package 在一个 Package 器bean中,该 Package 器bean将包含有关其顺序的信息。

  1. public class FlywayWrapper {
  2. private Flyway flywayConfig;
  3. private Integer order;
  4. }


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

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

展开查看全部
hsgswve4

hsgswve42#

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

相关问题