Flyway 的 CDI 扩展

Posted

技术标签:

【中文标题】Flyway 的 CDI 扩展【英文标题】:CDI Extension for Flyway 【发布时间】:2012-06-19 18:31:35 【问题描述】:

在 hibernate 连接到我的 JBoss AS 7.1 之前,我尝试在我的应用程序中运行 flyway。我尝试使用 @javax.ejb.Startup 注释,但是在初始化 Hibernate 并检查数据库方案后执行。

据我了解,我们可以使用在 Hibernate 初始化之前挂接的 CDI 扩展。 flyway开箱即用是否有一些支持?如果没有,有没有人尝试过这样做?

【问题讨论】:

我不认为有一个 J2EE 标准事件发生得足够早。您必须连接到特定于容器的接口。我不知道是否有人为 Flyway 这样做过,抱歉。您是否考虑过将其作为部署或启动脚本的一部分而不是应用程序启动? @TomAnderson 我已经考虑在我的部署脚本中执行 flyway 操作,我必须为此使用命令行 Flyway 工具。从文档中不清楚它是否也支持 Java 迁移,所以我想我只需要尝试一下;)我确信有一种方法可以在应用程序启动时实现这一点,因为 Liquibase 是可能的(参见@987654321 @)。我尝试了类似的方法,但不幸的是它在我的机器上不起作用.... @DominikObermaier 是的,Flyway 命令行确实支持 Java 迁移。它们可以作为 /jars 文件夹中的 jar 文件发送。 【参考方案1】:

好的,我终于知道了如何做到这一点:我必须使用 Hibernate 集成 API。这是我必须编写的全部代码:

public class FlywayIntegrator implements Integrator 

  @Override
  public void integrate(final Configuration configuration, final SessionFactoryImplementor sessionFactoryImplementor, final SessionFactoryServiceRegistry sessionFactoryServiceRegistry) 
    final Flyway flyway = new Flyway();

    flyway.setDataSource(....);
    flyway.migrate();
  

  @Override
  public void integrate(final MetadataImplementor metadataImplementor, final SessionFactoryImplementor sessionFactoryImplementor, final SessionFactoryServiceRegistry sessionFactoryServiceRegistry) 
    //no-op
  

  @Override
  public void disintegrate(final SessionFactoryImplementor sessionFactoryImplementor, final SessionFactoryServiceRegistry sessionFactoryServiceRegistry) 
    //no-op
  

如果有人对更多细节感兴趣,我创建了一个 github 项目来证明:https://github.com/dobermai/Hibernate-Flyway-Integration

【讨论】:

感谢您发布解决方案 Dominik。我在 jboss IRC 频道中阅读了你与 Scott 等人的对话,它把我带到了这里——很高兴你也创建了一个 githib 项目来演示它。 非常感谢。这真的帮助了我。要在 Integrator 上下文中从 JBoss 获取数据源,请使用以下命令:DataSource dataSource = InitialContext.doLookup("java:jboss/datasources/your-ds"); 如果可以直接从configurationsessionFactoryImplementorsessionFactoryServiceRegistry 执行此操作,那就太好了。我四处寻找,找不到数据源或它的 JNDI 名称。 :(。 您是如何设法让 Hibernate 加载集成器的?您是否必须按照此处的聊天协议中所述向 module.xml 文件添加一个条目:echelog.com/logs/browse/jboss-as7/1342562400? 它在您的代码人员上运行得很快吗?在 40 个迁移文件之后,这里非常慢。【参考方案2】:

CDI 定义了自己的生命周期,该生命周期在应用程序启动/停止时执行。 (你不应该已经知道了吗:This 是了解基本机制的好地方。)

据我所知,问题在于 Hibernate 初始化过程与 CDI 启动没有直接关联。这意味着我不确定依赖 Hibernate 和 CDI“事件”之间的关系是否安全。肯定没有什么比 CDI 事件 HibernateInitialized 更好的了。

话虽如此,我会试一试 :) 你应该实现一个简单的扩展,该扩展连接到 BeforeBeanDiscovery,这是尽早的。

This online presentation 概述了不同的 CDI 事件及其顺序。不幸的是,它是德语的。

【讨论】:

谢谢,我已经想通了,在 Hibernate 初始化之后会抛出 BeforeBeanDiscovery 事件。所以我想在 Hibernate 初始化之前不可能挂接(至少不是 CDI,也许有一些特定于 AS 的东西?)。

以上是关于Flyway 的 CDI 扩展的主要内容,如果未能解决你的问题,请参考以下文章

Flyway 始终执行可重复的迁移

Scala 中的自定义 Flyway 回调

Flyway:如何在 flyway 创建 flyway_schema_history 之前创建 SQL Server 数据库

Flyway - Flyway 架构迁移失败

flyway 无法连接到 docker-entrypoint-initdb.d 脚本中的 postgres 容器

flyway 后的 Flyway 迁移错误:基线