Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using both JPA EntityManager and Hibernate session with shared transaction manager in Spring

We have a hard situation.

  1. There is a large project which uses hibernate special features so cannot quit hibernate.
  2. We are to add Activiti process engine to the project in embedded mode and make use of JPA extensions (which only works with EntityManager)
  3. Some entities should not be present in JPA persistent unit because as activiti documentation says all entities must have @Id and cannot use @IdClass/@EmbeddedId so we have to exclude such entities from persistent unit
  4. We wish to use one shared transaction manager for EntityManager and Session. Also the dataSources are identical (or even shared)
  5. Everything is Spring!

All this effort is to enable Activiti to use EntityManager for its JPA extension while letting existing hibernate dependent codes to continue work.

like image 504
rabolfazl Avatar asked Dec 21 '12 15:12

rabolfazl


People also ask

Can we use Spring Data JPA and Hibernate together?

You cant actually use both of them in the same application.

Does the EntityManager use hibernate?

Hibernate provides implementation of JPA interfaces EntityManagerFactory and EntityManager .

Can Hibernate session have multiple transactions?

Obviously, you can. A hibernate session is more or less a database connection and a cache for database objects. And you can have multiple successive transactions in a single database connection. More, when you use a connection pool, the connection is not closed but is recycled.

Which PlatformTransactionManager s Can you use with JPA?

nanda is right, you can only use JpaTransactionManager. The Transaction Manager abstraction we are talking about here is Spring's PlatformTransactionManager interface, and JPATransactionManager is the only implementation of that interface that understands JPA.


1 Answers

First off, your 3rd point above may prove tricky to accommodate if you want to have one persistence unit and you're actually using @IdClass/@EmbeddedId in your Hibernate entities. Here are two possible solutions:

  1. Pull JPA into your project and configure a persistence unit for your existing Hibernate entities, but continute to delegate the existing calls to Hibernate by accessing the Session directly. In this case, your configuration would be moved over to JPA, but your code would not. This approach also assumes that you have some reasonable abstraction dispensing Session objects in a pluggable fashion. See this question for the crux of the solution. If you have zero flexibility on point 3 above, this approach may not be an option for you.

  2. Create both a session factory and persistence unit and coordinate transactions using JTA with two XA datasources. Even though your data may reside in the same database, you'll want to make sure you create distinct datasources in your configuration if you take this approach. This will prevent Spring's transactional proxy from getting confused when you participate in the distributed transaction. This is probably the cleanest approach, but does carry the stigma of XA transactions which, depending on your container, is more of a political problem these days than a technical one.

like image 114
jonathan.cone Avatar answered Oct 19 '22 20:10

jonathan.cone