Flyway Spring JPA2 integration - possible to keep

2019-07-22 20:27发布

问题:

Hy, i have a webapplication where i am trying to integrate JPA2(Hibernate)+Spring+Flyway

I added flyway to my ApplicationContext like this:

<bean id="flyway" class="org.flywaydb.core.Flyway" init-method="migrate">
    <property name="baselineOnMigrate" value="true" />
    <property name="dataSource" ref="dataSource" />
</bean>

Theoretically this works fine and updates the schema with scripts that i save under db/migration. So far so good.

The one problem that is left for me is that if i change something (e.g. adding a String field to an Entity) the application won't even get this far because Hibernates Schema-Validator will throw something like this: Caused by: org.hibernate.HibernateException: Missing column: showCaseField in demo.testEntity. This happens because i have set "hibernate.hbm2ddl.auto" to "validate"

Now i have read about Hibernate failing to recognize perfeclty valid schemas in some (rare?) cases and i MAY (or not) reach a point someday where i disable this feature altogether. But as of now i actually like the extra-validation and don't want to turn it off.

Is it possible to integrate Spring and Flyway while still keeping Hibernates-Schema-Validation? I guess this could be a problem, because Flyway probably depends on a DataSource-bean or something and in conclusion requires the applicationContext to be completely initialized, which in turn Hibernate prevents because of the schema mismatch..

Any ideas?

回答1:

Found the answer now. Basically all you have to do is letting your entityManagerFactory-bean depend on your Flyway bean (there's an attribute for that). Now Flyway (and in turn your dataSource) is initialized first and the Flyway-Scripts are executed before Hibernates schema-validation

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    depends-on="flyway"> ....
</bean>
<bean id="flyway" class="org.flywaydb.core.Flyway" init-method="migrate">
    <property name="baselineOnMigrate" value="true"/>
    <property name="dataSource" ref="dataSource"/>
</bean>