Hibernate + Liquibase: design choices and best practises?

While being involved with analyzing a bug fix within the Bahmni project, I started digging on OpenMRS’ use of Hibernate and Liquibase and would like to shed some light.

We don’t let Hibernate generate tables

While we do define Hibernate mappings to setup entities, we don’t use Hibernate to generate tables. Example on Obs:

  • Hibernate: Obs.hbm.xml and here in hibernate.cfg.xml.
  • Liquibase: here (and elsewhere in this file for foreign key constraints… etc).

Q1. Why was it decided to not use hibernate.hbm2ddl.auto in hibernate.default.properties?

We don’t hook Liquibase to the Hibernate mappings

As an alternative to using hibernate.hbm2ddl.auto it is possible to hook Liquibase onto the HBM. And let Liquibase detect changes and apply the relevant migrations automatically.

Q2. Was this ever considered?

Cc: @dev5 @angshuonline

P.S. At this point I think I have a pretty good idea about what the above answers might be. I.e. limitations of hibernate.hbm2ddl.auto, caution about automatic migrations, requirement to upgrade to Hibernate 5.x… etc. But I would like to revisit the historical design choices to better document it here, and then hopefully in the wiki for the next generation of developers that will be involved in expanding or appending the data model.

I doubt if it’s recommended to use hibernate.hbm2ddl.auto in production, I don’t think this is from the hibernate team but from other longtime hibernate users, the tool generates random unique and foreign key names, in some cases you want to have control over these names, also depending on how you map your entities, the tool can generate the schema in an alternative way especially for one-to-one and many-to-many relationships.

Sometimes tech survey users might want to make schema changes and possibly pre-populate data into some tables before an upgrade or installation for those migrating from other systems, this would be nearly impossible with hibernate.hbm2ddl.auto.

There is a SpringLiquibase class that can be hooked into spring to automatically run liquibase changesets when the application context it starting, also I think via a ServletListener but I guess they were not supported at the time when liquibase was first introduced in OpenMRS, and the downside to this is that you lose a step in the startup process which can be useful for admins to make prep tasks before an upgrade or installation since the updates would’ve already happened, probably there could be an alternative way but it would be a little more complex.

1 Like

Actually the hibernate documentation discourages using the update option of hbm2ddl.auto in production here and here.

1 Like

Thanks @wyclif, very useful.