Nitek Nitek - 4 months ago 30
Java Question

Run SpringLiquibase BEFORE Hibernate

I'm using SpringLiquibase to apply my liquibase update automatically during the application startup. In general this works fine, but when I set hibernate.hbm2ddl.auto to "validate" then hibernate starts to complain about the database scheme before liquibase seems to have the chance to apply the updates.
My configuration looks like this:

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "com.myapp")
@PropertySource(value = {"classpath:myapp.properties"})
@EnableJpaRepositories("com.myapp")
public class MyappConfig {

@Resource
private Environment env;

@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();

dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driver"));
dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
dataSource.setUsername(env.getRequiredProperty("jdbc.username"));
dataSource.setPassword(env.getRequiredProperty("jdbc.password"));

return dataSource;
}

@Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource());
liquibase.setChangeLog("classpath:liquibase/liquibase-master-changelog.xml");
return liquibase;
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan("com.myapp");

entityManagerFactoryBean.setJpaProperties(hibernateProperties());

return entityManagerFactoryBean;
}

private Properties hibernateProperties() {
Properties properties = new Properties();

String[] propertyNames = new String[]{"hibernate.dialect", "hibernate.show_sql", "hibernate.hbm2ddl.auto"};

for (String propertyName : propertyNames) {
properties.put(propertyName, env.getRequiredProperty(propertyName));
}
return properties;
}

@Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}

}


Is there any way to get liquibase to apply its updates BEFORE hibernate tries to validate the schema?

Answer

Thanks to M. Deinum I was able to solve this by using

@Bean
@DependsOn("liquibase")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
   [...]
}

The @DependsOn makes sure that liquibase is run before Hibernates schema validation.