Keeping your database schemas in sync with your model

Hibernate’s hbm2ddl.auto setting allows you to create, update, and validate a database schemas based on the mapping configuration. The create & update settings are great in development environments, since they will ensure your database schema will always be in sync with your model. We would not recommend these settings in an production environment because, there we need to have more fine grained control over database updates (hbm2ddl is too “magical” for production). Additionally, there may be updates to the data which cannot be handled by Hibernate’s hbm2ddl.auto implementation (e.g. content-related updates rather than structural).

Some people would say, “such database updates should not be done by the application, but rather by the database administrator”. However, for most applications, you want the code to maintain the database structure – otherwise you have terrible trouble keeping test and staging databases up to date.

To achieve this we “upgrade” our databases with our own implementation, using plain JDBC. A meta table in the schema holds a version number which gets checked during the application’s start up. If the version in the database does not match the code version, the application upgrades the database schema accordingly.

We need to have our own database upgrade execute before Hibernate intercepts. Otherwise Hibernate will complain that tables or columns which should be created by our upgrade procedure are not yet available.

This can be achieved by a bean, which implements the BeanFactoryPostProcessor.

package sample;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class DatabaseVersion implements BeanFactoryPostProcessor {

 public static void checkDatabaseStructure() {
  /*
   * This method creates a generic JDBC connection,
   * checks the database structure
   * and upgrades it if applicable.
   */
 }

 @Override
 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
  DatabaseVersion.chekDatabaseStructure();
 }
}

All what’s missing now is the definition of the bean in the applicationContext.xml file.


That’s it. The application context auto-detects BeanFactoryPostProcessor beans in their bean definitions and applys them before any other beans get created. If you are concearned about the order of loading, your bean can implement the “Ordered” interface in addition.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.