Non-backwards-compatible changes to Hibernate's Type API

Between Hibernate 3.2.5 and 3.6, Hibernate rewrote their Type system in a non-backwards-compatible way. Their very limited documentation of this is their ticketing system: HHH-5138.

If you have any custom UserTypes, your module will probably break when you try to use it in 1.9.

Hibernate.INTEGER, Hibernate.STRING, etc, no longer exist

The static constants Hibernate.INTEGER, Hibernate.STRING, etc, no longer exist. The symptom of this is your module failing to load, with an error message like  If you see an error like 

java.lang.NoSuchFieldError
INTEGER

If you want your module to only be compatible with OpenMRS 1.9+, you can just change your code to use the constants in org.hibernate.type.StandardBasicTypes instead.

If (more likely) you want your code to run in pre-OpenMRS 1.9 and also OpenMRS 1.9+, you may have to do a bit more work.

In some cases, you can just remove unnecessary usage of Hibernate types:

  • use constants from java.sql.Types instead of hibernate types, like in this example in the Reporting module.
  • let Hibernate automatically detect underlying types, like in this example from the HTML Form Entry module.

In other cases, you may have to do more work. A complex example from the Reporting module is here.

NullableType is deprecated, breaking GenericEnumUserType

UserType code commonly referred to the abstract NullableType class. This class was deprecated in Hibernate, and the standard types no longer extend it. As a result, many variations of GenericEnumUserType code from the web (including the one the Reporting module borrowed) break. Here is the working GenericEnumUserType from the Reporting module, which requires the sqlType method from the HibernateUtil class.

In the general case, you may want to write your code against Hibernate 3.2.5 (included in a lower required version of OpenMRS) and use reflection to handle the Hibernate 3.6.5 case. The Reporting module has a complex example of this.