It's not legal to coordinate transactions manually in JTA. I created a test for this use case:
Code:
try(Session session1 = entityManagerFactory.unwrap(SessionFactory.class).openSession()) {
session1.beginTransaction();
try(Session session2 = entityManagerFactory.unwrap(SessionFactory.class).openSession()) {
session2.beginTransaction();
session2.getTransaction().commit();
}
session1.getTransaction().commit();
}
When I try to run it, I get:
Quote:
java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
at org.hibernate.internal.AbstractSharedSessionContract.getTransaction(AbstractSharedSessionContract.java:382)
at org.hibernate.internal.AbstractSharedSessionContract.beginTransaction(AbstractSharedSessionContract.java:408)
at com.vladmihalcea.book.hpjp.hibernate.connection.jta.JtaMultipleTransactionsTest.test(JtaMultipleTransactionsTest.java:35)
which is fine since we are in a JTA environment.
What you need to do is let the JTA TransactionManager do the management for you.
Code:
transactionTemplate.execute((TransactionCallback<Void>) transactionStatus1 -> {
try(Session session1 = entityManagerFactory.unwrap(SessionFactory.class).openSession()) {
transactionTemplate.execute((TransactionCallback<Void>) transactionStatus2 -> {
try(Session session2 = entityManagerFactory.unwrap(SessionFactory.class).openSession()) {
}
return null;
});
}
return null;
});
Which works like a charm. Use the Java EE application server to coordinate that for you.