从版本6.* 开始,Flyway支持Spring bean注入到java迁移文件中,并实现了JavaMigration
接口。下面是我的示例:
@Component
public class V1_201809261821__some_migration extends BaseJavaMigration {
@Autowired
private SomeDAO someDAO;
@Override
public void migrate(Context context) throws Exception {
someDAO.doSomething();
}
}
启动时,它会抱怨:
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
v1_201809261821__some_migration (field private SomeDAO V1_201809261821__some_migration.someDAO)
┌─────┐
| someDAO (field private org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate someDAO.namedParameterJdbcTemplate)
↑ ↓
| flywayInitializer defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]
↑ ↓
| flyway defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]
↑ ↓
| v1_201809261821__some_migration (field private SomeDAO V1_201809261821__some_migration.someDAO)
└─────┘
似乎我不能在Java迁移文件中使用JdbcTemplate
,Flyway的文档显示我可以使用Context
构建自己的JdbcTemplate
,如下所示:
public void migrate(Context context) {
new JdbcTemplate(new SingleConnectionDataSource(context.getConnection(), true))
.execute("INSERT INTO test_user (name) VALUES ('Obelix')");
}
但不幸的是,我无法控制SomeDAO
,它来自另一个模块,我无法触摸。
相关版本:
- 飞行路线:6.0.6
- Sping Boot :2.2.0
4条答案
按热度按时间zte4gxcn1#
这就是Sping Boot 决定集成Flyway的原因。在默认的自动配置中,在完成Flyway迁移之前,您无法对数据库做任何事情。这是一个明智但固执己见的选择。
看一下FlywayAutoConfiguration的源代码。有一个相当讨厌的技巧来确保在Flyway准备好之前没有人可以使用JdbcTemplate:
为了实现你的目标,你必须禁用这个自动配置(
spring.autoconfigure.exclude
),自己编写Flyway配置。你可以从FlywayAutoConfiguration
的源代码开始,但是要去掉那些棘手的方法。但是,您必须添加一个类似的依赖技巧,以确保您的服务/作业仅在您的自定义Flyway准备就绪后才启动。
zqry0prt2#
我对这个特性也很兴奋,但很失望地发现,在某种程度上依赖于持久层的类是不可能自动连接的。但Flyway Spring Boot Autowired Beans with JPA Dependency中描述的解决方案仍然有效:
首先扩展
FlywayConfiguration
:第二,创建这个类以从应用程序上下文获取Bean:
现在您可以在java迁移类(
extends BaseJavaMigration
)中使用这个类来获取您想要的任何Bean。fzwojiic3#
没有向下看堆栈,但我猜Flyway作为迁移工具不希望您在更改数据时将其结构化。
其他(非数据访问)服务被注入并且可以被使用。
你可以从上下文中获取数据库连接,并使用jdbc模板进行更改。
xeufq47z4#
我的情况是
1.我使用@Lazy注解来使相关的bean延迟初始化,
1.添加Spring配置:
allow-circular-references: true
到applition yml然后flyway可以启动并成功处理。这就是我发现的为什么以及如何flyway导致循环引用:
就像上面的答案说的,Flyway migrate支持改变表结构的DDL,所以不希望你在迁移时注入jpa bean。
Spring(我的版本2.7.9)有FlywayAutoConfiguration注解
@Import(DatabaseInitializationDependencyConfigurer.class)
,生成的数据源配置将依赖于flyway和flywayInitlizer,并且必须在flyway完成后进行数据源初始化。但是有时候我们需要它来做一些事情,比如在Java代码中插入或更新数据(我的例子)。在Flyway的帮助下,我们可以同时受益于自动SQL迁移和定制的Java代码。