2012-06-17 38 views
16

在hibernate連接到我的JBoss AS 7.1之前,我嘗試在我的應用程序中運行flyway。我嘗試了一個@javax.ejb.Startup批註,但是這會在Hibernate初始化並檢查數據庫方案後執行。Flyway的CDI擴展

所以據我所知,我們可以使用CDI擴展,它在Hibernate初始化之前掛鉤。 flyway有沒有一些開箱即用的支持?如果沒有,有沒有人試圖做到這一點?

+0

我不認爲有這恰好一個J2EE標準事件爲此早就夠了。你將不得不接入容器特定的接口。我不知道有沒有人爲Flyway做過這件事,對不起。您是否考慮將其作爲部署的一部分或啓動腳本而不是應用程序啓動? –

+0

@TomAnderson我已經考慮在我的部署腳本中執行flyway動作,因此我必須使用Command Line Flyway Tool。從文檔中不清楚它是否也支持Java Migrations,所以我想我只需要嘗試一下;) 我確信有一種方法可以在應用程序啓動時實現此目的,因爲它可以使用Liquibase(請參閱https://github.com/aaronwalker/liquibase/commit/5be42a6779b2bef95e2d02d8703aceec91aedb59)。我嘗試過類似的東西,但不幸的是它不能在我的機器上工作。...... –

+1

@DominikObermaier是的,Flyway Command Line確實支持Java遷移。它們可以作爲jar文件運送到/ jars文件夾中。 –

回答

28

好吧我終於找到了如何做到這一點:我不得不使用Hibernate Integration 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

+1

感謝您發佈您的解決方案Dominik。我閱讀了與Scott等人在jboss IRC頻道的對話,並將它帶到了這裏 - 您創建了一個githib項目來演示它也非常棒。 – user1180316

+3

非常感謝。這真的幫助了我。要在Integrator上下文中從JBoss獲取數據源,請使用以下代碼:DataSource dataSource = InitialContext.doLookup(「java:jboss/datasources/your-ds」); – homaxto

+0

如果可以從'configuration','sessionFactoryImplementor'或'sessionFactoryServiceRegistry'這樣做,那真是太好了。我捅了一圈,找不到數據源或它的JNDI名稱。 :(。 – danieljimenez

1

CDI定義了它自己的生命週期,它在應用程序啓動/停止時執行。 (你不應該知道它:This是瞭解基本機制的好地方。)

問題 - 就我的最佳知識而言 - Hibernate初始化過程不直接鏈接到CDI啓動。這意味着我不確定它是否安全依賴於休眠& CDI「事件」之間的關係。肯定沒有像CDI事件HibernateInitialized。在說了這些之後,我會試一試:)你應該實現一個簡單的擴展,該擴展在BeforeBeanDiscovery處掛起,這個擴展儘可能早。

This online presentation概述了不同的CDI事件及其順序。不幸的是,這是德文。

+1

謝謝,我已經想通了,在Hibernate初始化之後拋出BeforeBeanDiscovery事件。所以我想在Hibernate初始化之前不可能掛鉤(至少不用CDI,也許有特定的東西?)。 –