我正在使用Flyway 5.0.5,并且无法创建具有自动装配属性的java(SpringJdbcMigration)…它们最终会出现null。
null
答案提到它已在Flyway 5中修复,但链接已失效。
我想念什么?
由于依赖JPA,我为此苦了很长时间。我将略微修改我的问题的标题以反映这一点。
@AutowiredBean是从实例化的ApplicationContext。我们可以创建一个不同的bean,ApplicationContextAware然后使用它“手动连接”我们的bean以供迁移。
@Autowired
ApplicationContext
ApplicationContextAware
在这里可以找到一种非常干净的方法。不幸的是,ApplicationContext使用JPA时会引发未捕获的异常(特别是null)。幸运的是,我们可以通过使用@DependsOn注释并ApplicationContext在设置之后强制飞行来解决此问题。
@DependsOn
首先我们需要SpringUtility从avehlies/spring-beans- flyway2以上。
SpringUtility
avehlies/spring-beans- flyway2
package com.mypackage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringUtility implements ApplicationContextAware { @Autowired private static ApplicationContext applicationContext; public void setApplicationContext(final ApplicationContext applicationContext) { this.applicationContext = applicationContext; } /* Get a class bean from the application context */ public static <T> T getBean(final Class clazz) { return (T) applicationContext.getBean(clazz); } /* Return the application context if necessary for anything else */ public static ApplicationContext getContext() { return applicationContext; } }
随后,将配置flywayInitializer有@DependsOn供springUtility。我扩展了FlywayAutoConfiguration此处,希望保留自动配置功能。除了在gradle.build文件中关闭flyway不再起作用之外,这似乎对我来说一直有效,因此我不得不添加,@Profile("!integration")以防止它在测试期间运行。除此之外,自动配置似乎对我有用,但是坦白地说,我只运行了一次迁移。希望如果我错了,有人会纠正我。
flywayInitializer
springUtility
FlywayAutoConfiguration
@Profile("!integration")
package com.mypackage; import org.flywaydb.core.Flyway; import org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer; import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.DependsOn; import com.mypackage.SpringUtility; @Configuration @Profile("!integration") class MyFlywayConfiguration extends FlywayConfiguration { @Primary @Bean(name = "flywayInitializer") @DependsOn("springUtility") public FlywayMigrationInitializer flywayInitializer(Flyway flyway){ return super.flywayInitializer(flyway); //return new FlywayMigrationInitializer(flyway, null); } }
为了完成示例,下面是一个迁移:
package db.migration; import org.flywaydb.core.api.migration.spring.BaseSpringJdbcMigration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import com.mypackage.repository.AccountRepository; import com.mypackage.domain.Account; import com.mypackage.SpringUtility; import java.util.List; public class V2__account_name_ucase_firstname extends BaseSpringJdbcMigration { private AccountRepository accountRepository = SpringUtility.getBean(AccountRepository.class); public void migrate(JdbcTemplate jdbcTemplate) throws Exception { List<Account> accounts = accountRepository.findAll(); for (Account account : accounts) { String firstName = account.getFirstName(); account.setFirstName(firstName.substring(0, 1).toUpperCase() + firstName.substring(1)); account = accountRepository.save(account); } } }
感谢github上的avehlies,堆栈溢出的Andy Wilkinson和github上的OldIMP一直为我提供帮助。
如果您使用的是Flyway的最新版本,请扩展BaseJavaMigration而不是BaseSpringJdbcMigration不推荐使用。另外,请查看用户Wim Deblauwe 的以下两条 评论。
BaseJavaMigration
BaseSpringJdbcMigration