SessionFactory issue after Hibernate 4 upgrade

So… if we start to work on this and find modules using core versions earlier than 1.9, we take the liberty of updating them to 1.9.10 (after it is released)? For instance I went to update Atlas and found that it is built against 1.7.4. Just want to make sure this is the right approach and find out if there are any caveats around jumping modules up by several core version numbers.

Yes, the required version of OpenMRS Platform will have to be upgraded to 1.9.9 (released to maven yesterday, not yet announced) in order to use DbSessionFactory in Atlas and other modules.

It’s slightly more complicated than that, right? Eg. 1.10.0 is not supported, so there would need to be minimum and maximum ranges defined for 1.9.x, 1.10.x, and 1.11.x

To be precise in config.xml you would use <require_version>1.11.3, 1.10.2 - 1.10.*, 1.9.9 - 1.9.*</require_version> and in pom.xml you would use 1.9.9 as the openmrs-api dependency version. See the updated pull request for htmlformentry module at:

Just to focus on the “take the liberty of updating them” point:

Can you share a list of the modules that are going to need this treatment (ideally with what their current min-openmrs-versions are)?

We are certainly moving towards more ruthlessly updating modules to require recent, supported, openmrs-core versions, but it’s nice to at least see the impact this will have (for something that will provide zero end-user value to any implementation this calendar year).

fyi, this would be a blocker for us updating modules to requires 1.10.2:

I think it’s worth reconsidering Burke’s idea of introducing a library for DbSession, as opposed to adding DbSession to new 1.9 and 1.10 core releases. In theory it sounds nice to get everyone up to a recent 1.9 and 1.10 dot release but in practice this approach means that with every module that we add DbSession support to, we are forcing implementors to upgrade core in the short term (which has already proven problematic in a couple of cases). Introducing a library dependency would be a safe way to solve this problem and would scale all the way back to modules depending on 1.7, 1.8 etc.

@kristopherschmidt, the way to implement that would be to create a new module, with DbSession and DbSessionFactory and configure other modules to be aware of that new module. If one can’t upgrade to the latest version, that new module can be installed instead. Would you like to code it up?

Yes I can code that up. Any suggestion for module naming? I was thinking along the lines of hibernatecompatibility, to make its purpose clear. Unless you want to stick with dbsession or dbsessioncompatibility to mirror the class names.

1 Like

I like hibernatecompatibility :slight_smile:

I like hibernatecompatibility too. As always it’s best to consult the module name by writing to https://talk.openmrs.org/c/developers/repo-management with a request to create a github repo.

I created the hibernatecompatibility module at https://github.com/kristopherschmidt/openmrs-module-hibernatecompatibility, and was testing it against an updated namephonetics that I created at https://github.com/kristopherschmidt/openmrs-module-namephonetics/tree/NP-10

It all works fine against core 1.11.2 with hibernatecompatibility, and against core 1.11.3 without hibernatecompatibility, but unfortunately I ran into further Hibernate4 complications with namephonetics when running against core 1.12-SNAPSHOT, apparently some other classes have changed incompatibly:

java.lang.AbstractMethodError: org.openmrs.module.namephonetics.NameFieldUserType.nullSafeSet(Ljava/sql/PreparedStatement;Ljava/lang/Object;ILorg/hibernate/engine/spi/SessionImplementor;)V
	at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:158)
	at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2843)

I was also trying to test against atlas but the OpenMRS login is giving me a 503 at https://id.openmrs.org/authenticate/atlas (yesterday and today). Is that a production server issue?

Any thoughts on either of these?

Bad news, the signatures of nullSafeGet/Set have changed:

https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/usertype/UserType.html https://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/usertype/UserType.html

The signature change is further explained here: https://hibernate.atlassian.net/browse/HHH-5968

Another thing I discovered is that some modules like namephonetics that rely on versions of OpenMRS pre-core-1.9 are compiling against Hibernate 3.2 (from 1.9 on it was Hibernate 3.6). On Hibernate 3.6 there are potential replacements for the nullSafeGet/Set methods that were deprecated, but on Hibernate 3.2 those methods weren’t even deprecated yet so there aren’t even alternatives.

I’m not sure what this means in terms of trying to fix namephonetics. For now I’m moving on to testing hibernatecompatibility against a different module.

That’s too bad :confused: More issues like this can be observed whenever module is using Hibernate API, which changed. Fortunately, the custom type signature is the last such change that I remember fixing in core.

I would work around this by getting rid of NameFieldUserType, declaring the nameField field as an int (but not getter/setter) and doing the conversion in a getter and setter. It also implies setting access=“field” on the property in hbm and correcting hql and criteria queries to pass int values.

So…apart from the issues with namephonetics, I have tested hibernatecompatibility against an updated atlas module and it all works fine, so I’ll make a request to create a github repo. Then I suppose this thread’s initial post and the corresponding JIRA cases will need to be modified to explain the new approach. All modules using Hibernate will need to be updated to use hibernatecompatibility similar to the following:

https://github.com/openmrs/openmrs-module-atlas/compare/master...kristopherschmidt:ATLAS-118

I tested atlas in 3 scenarios:

  1. with 1.11.2/Hibernate3 using hibernatecompatibility
  2. with 1.11.3/Hibernate3 without hibernatecompatibility (using core DbSessionFactory)
  3. with 1.12-SNAPSHOT/Hibernate4 without hibernatecompatibility (using core DbSessionFactory)

Note I kept the org.openmrs.api.db.hibernate packaging of DbSession/Factory in the hibernatecompatibility module (even though that is against convention), so that it is seamless switching between the use of DbSession/Factory coming from the module, and DbSession/Factory coming from an upgraded core.

Just as a side note, I imagine that from openmrs-core 1.11.x it would be best to completely rewrite namephonetics to use lucene or hibernate-search directly. But that is obviously a bigger task.

So, for clarification, any users of 1.9.x, 1.10.x, and 1.11.x branches would need to now install the hibernate-compatibility module to use the latest versions of modules that require this upgrade?

Also, what about scenario 4: would it work with 1.11.3/Hibernate 3 with hibernatecompatibility, or would end users have to remember to uninstall this module when upgrading from 1.11.2 to 1.11.3?

Correct @mogoodrich, anyone using core 1.8 or less, 1.9.0-1.9.8, 1.10.0-1.10.1, or 1.11.0-1.11.2 would need to install the hibernatecompatibility module. This is documented on the module’s new github page: https://github.com/openmrs/openmrs-module-hibernatecompatibility

I will test out your scenario 4. I would assume that the module could coexist with the classes in core when upgrading (since they are identical), so there would be no pressing need to uninstall the module, but this needs testing to make sure.

Okay, makes sense. @burke @darius probably makes sense to have a chat about this on the design call to make sure we are on the same page for messaging around this?

From a PIH perspective, sounds like there shouldn’t be much of an impact, however, in the community, I could see confusion if the latest versions of each module start to fail cryptically because the implementation hasn’t installed the hibernate compatibility module.