2012-06-17 12 views
16

Intenté ejecutar flyway en mi aplicación antes de que hibernate se enganche en mi JBoss AS 7.1. Intenté con una anotación @javax.ejb.Startup, pero esto se ejecuta DESPUÉS de que se inicialice Hibernate y se verifique el esquema de la base de datos.CDI Extension for Flyway

Por lo que entiendo, podemos usar una extensión CDI que se engancha antes de que se inicialice Hibernate. ¿Hay algo de apoyo para eso fuera de la caja para la ruta migratoria? Y si no, ¿alguien ha tratado de hacer esto antes?

+0

No creo que haya un evento estándar J2EE lo que sucede lo suficientemente temprano para esto. Debería conectar las interfaces específicas del contenedor. No tengo idea de si alguien hizo eso para Flyway, lo siento. ¿Ha considerado hacerlo como parte de su implementación o secuencia de comandos de inicio en lugar de como inicio de la aplicación? –

+0

@TomAnderson He considerado hacer la acción flyway en mi script de implementación, tengo que usar la herramienta Command Line Flyway Tool para eso. No está claro en la documentación si también admite Java Migrations, así que supongo que tengo que probarlo;) Estoy seguro de que hay una forma de lograr esto en el inicio de la aplicación, porque es posible con Liquibase (ver https://github.com/aaronwalker/liquibase/commit/5be42a6779b2bef95e2d02d8703aceec91aedb59). Intenté algo similar, pero lamentablemente no funciona en mi máquina ... –

+1

@DominikObermaier Sí, Flyway Command Line es compatible con migraciones de Java. Se pueden enviar como archivos jar dentro de la carpeta/jars. –

Respuesta

28

Ok, finalmente descubrí cómo hacer esto: tuve que usar la API de integración de Hibernate. Este es todo el código que tenía que escribir:

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 
    } 
} 

Si alguien está interesado en más detalles, he creado un proyecto github que demuestra que: https://github.com/dobermai/Hibernate-Flyway-Integration

+1

Gracias por publicar su solución Dominik. Leí tu conversación con Scott, etc. en el canal de IRC de jboss, y me llevó hasta aquí. Es fantástico que hayas creado un proyecto githib para demostrarlo también. – user1180316

+3

Muchas gracias. Esto realmente me ayudó. Para obtener una fuente de datos de JBoss en el contexto de Integrator, use esto: DataSource dataSource = InitialContext.doLookup ("java: jboss/datasources/your-ds"); – homaxto

+0

Sería genial si fuera posible hacerlo desde la 'configuración',' sessionFactoryImplementor' o 'sessionFactoryServiceRegistry'. He hurgado y no puedo encontrar la fuente de datos o su nombre JNDI. :(. – danieljimenez

1

CDI define su propio ciclo de vida que se ejecuta cuando una aplicación se inicia/detiene. (¿No debería saberlo ya ?: This es un buen lugar para aprender sobre el mecanismo básico.)

El problema, según mi leal saber y entender, es que el proceso de inicialización de Hibernate no está directamente relacionado con el arranque del CDI. Esto significa que no estoy seguro si es seguro confiar en una relación entre Hibernate & CDI "events". No hay nada como un CDI-Event HibernateInitialized.

Habiendo dicho esto, lo probaría :) Debería implementar una extensión simple que se conecta al BeforeBeanDiscovery, lo más pronto posible.

This online presentation ofrece una descripción general de los diferentes eventos de CDI y su orden. Está en alemán, desafortunadamente.

+1

Gracias, ya me di cuenta, que el evento BeforeBeanDiscovery se produce después de que se inicializa Hibernate. Así que supongo que no es posible enganchar antes de que Hibernate se inicialice (al menos no con CDI, ¿tal vez haya algo AS específico?). –