Following up with a clarification. After looking at this again it
doesn't look like the Session path has this problem. Instead the
EntityManager path of:
1. start a JTA transaction programmatically
2. check there is a current session
associated(SessionFactory.getCurrentSession()). I only mention this
since the session I get with currentSession is not the same session
the produced entitymanager uses.
3. call entityManagerFactory.createEntityManager()
4. try to execute some JPA
query(entityManager.createQuery().executeUpdate()), and I get a
TransactionRequired Exception.
Specifically I'm looking at the EntityManager path of:
AbstractQueryImpl->executeUpdate->AbstractEntityManagerImpl->isTransactionInProgress->SessionImpl.isTransactionInProgress->TransactionCoordinatorImpl->JtaTransaction->isActive()
Which again the local status is not active. When debugging I can also
see the underlying session is not the same session that I got from
currentSession(). Also before local status is checked I see the path
of
SessionImpl->checkTransactionStatus->Coordinator.pulse()->attemptToRegisterJtaSync
is executed. But transactionContext.autoJoinTransaction is false, so
the user transaction is never looked up.
It seems off to me that the entityManager produced after I started the
transaction is using a different underlying Session. Is that correct
or not correct?
Again something seems broken or incredibly non-obvious here,
especially since this worked in 3.x. Would love some feedback, but
until then I'm going to start boiling this into a testcase so its
really clear what my expectations are.
ZK
On Wed, May 9, 2012 at 10:47 AM, Zachary Kurey <zackurey(a)gmail.com> wrote:
Hi all,
Am I correct in my interpretation that Hibernate 4 no longer supports
interchangeably being able to use either the Hibernate transaction
facade(session.beginTransaction) vs. UserTransaction or CMT?
I say this because it appears that I always must call
session.beginTransaction() when configured to use
JTATransactionFactory, in order to have JtaTransaction->local status
of active. If local status is not active Hibernate makes no attempt
to check the provided JtaPlatform if there is a user transaction in
process and blows up whenever trying to execute any changes to the db.
In 3.x this worked fine since
JTATransactionFactory->isTransactionInProgress always tried to find
the configured transaction manager and checked the transaction status
properly. But in 4.x I'm not seeing how local status gets set to
active to prevent a blow up unless I both call userTransaction.begin()
AND session.beginTransaction()... The same problems exist when
interacting through the EntityManager API.
Even in the ManagedDrivingTest it looks like it is assumed that the
client will call session.beginTransaction() after either a CMT or BMT
has been started. I would cut over to using the Hibernate facade
exclusively, but now it throws 'nested transactions not supported' if
beginTransaction is invoked multiple times. The Spring
PlatformTransactionManager API deals with multiple layered invocations
more gracefully, so I've mostly used that in the past for programmatic
transaction management. But regardless, looking at the source there
seems to be a new requirement to always have
session.beginTransaction() invoked in application code.
I've spent days trying to figure out if I've made a configuration
mistake, and at this point I'm at the conclusion that either Hibernate
behavior in this area was intentionally changed, or that this is a
bug. If its a bug it would probably break a lot of apps upgrading
from 3.x to 4.x that use programmatically controlled transactions. So
I thought I'd just reach out on the mailing list for clarification, or
to have an obvious misconfiguration or misunderstanding corrected.
For more info on my JTA config there is a forum post I made that is
unrelated(realized my error on that topic) here:
https://forum.hibernate.org/viewtopic.php?p=2454363
Thanks,
Zach