Supporting JPA in OpenMRS

Have we ever thought about providing container-agnostic persistence layer using JPA over Hibernate & Spring from OpenMRS?

I know that @raff posted about this here

However, looking at the example and also how the hibernate session factory is configured I am not sure if we can really leverage “EntityManager” abstraction. If we are going to leverage JPA, then I think it ought to be ORM library agnostic. In the example here, we are still using hibernate session factory and just leveraging the annotations.

Note, to do this, we would change in core for how we configure our dataSource, transaction manager etc.

Do we want to do this?

From my understanding, hibernate is an implementation of JPA and conforms to the specification, if you used only JPA, you would be very limited on what you can do. Hibernate provides a whole lot of features that you don’t get with the standard JPA which are required by a complex system like OpenMRS and it also supports standard JPA features like annotations. All I can say is that our role is to promote usage of standard JPA features along with hibernate e.g use JPA annotations vs hibernate annotations where possible so that in the event of switching to another JPA compliant ORM tool even if I don’t see this happening, some things wouldn’t have to be changed.

1 Like

I remember a discussion where someone explained that if we wanted to truly support JPA we’d end up needing to maintain a JPA EntityManager alongside a Hibernate one. (Maybe for backwards compatibility?) However I can’t find any trace of this discussion…

@angshuonline, what would be the concrete reason for doing this? Is there something you’d want to be able to do with a JPA EntityManager that you can’t currently do with OpenMRS?

@wyclif: understood. I think it would take too much to convert all our DAOs to work over JPA entity manager abstraction. However, we can definitely expose an EntityManager interface as well. The benefit that I see is that a library need not depend on hibernate.

@darius: I was thinking in terms of plugging external libraries. one of things that I am struggling with

  • how do I make the atomfeed core library pluggable? meaning, anybody should be able to have dependency to the core libraries, instantiate the needed objects (ex EventService) and have them participate in the same ongoing transaction? I can definitely make the library use hibernate session factory (and have it injected), then the library itself is dependent on Hibernate, whereas the aim for the library was to have the persistence abstracted out from ORM. (like it does it JDBC abstractions)

Alternately, without this, I am forced to create another separate library.

Any idea whether there’s a performance implication of this? (E.g. might it have a non-trivial memory footprint?)

Would we expect the JPA entity manager and the Hibernate session factory to be bridged, and just magically work together?

You will need a datasource definition (c3p0 combopooleddatasource?), a JPA transaction manager and a hibernate specific JPA adapter in addition to the EntityManager.

I would imagine that the memory footprint would be insignificant. However, I am not sure whether we can have a JpaTransactionManager and a HibernateTransactionManager (for existing codebase) working together.

Usually you have one single PlatformTransactionManager in an application. :frowning: Its possible to use 2 different transactionManager in spring container, but then you need to use a qualifier value and use it in combination with @Transactional(“txMgrName”). Surely we aren’t doing it this way!

OK, given the case, I think I will have to write another library with dependency on HibernateSessionFactory so that the core library then can participate in the same transaction!

Reloading this topic. I see that on openmrs-core, there are commits already for introduction on JPA annotations. Is there any associated talk thread I can follow on this or community call notes?

  1. I am wondering whats the expectations from other distros and/or modules
  2. How are others considering the migration? What if there is a need to support distro over core 2.1 and 2.3?
  • maintain two different versions? branches? this can get messy!
  • or support HBM files as well as JPA annotations?
  • or figure out a way to support both (like using Spring Profile)

attention: @dkayiwa, @darius @burke @mksd @wyclif

So right now we have a mixed bag in Core of entities that are defined 1) via HBM XML config files or 2) with JPA annotations. And as far as I know (but @wyclif to step in and contradict me if need be), that’s fine and doesn’t require anything from anyone.

Or @angshuonline, what issues do you anticipate?

This is correct, and everything else that you have said. :slight_smile:

@mksd is correct, it perfectly fine to mix annotations and hbm files.

1 Like

My recollection (maybe out-of-date) is that modules can use JPA annotations just fine, except that you can’t use them for subclasses of Order (or any subclass of a core class that’s defined with hbm.xml).