Hello,
we are seing the exact same problems (SERIOUSLY bad performance) with "hibernate-JPA".
Alone creating an EntityManager from EntityManagerFactory results in 4 lookups.
What happens is that the WebSphereExtendedJTATransactionLookup looks up the "extendedJTATransaction" support named "java:comp/websphere/ExtendedJTATransaction" from a new InitialContext each time a Transaction (TransactionAdapter) is needed.
The way the Hibernate EntityManger (actually the Session) is implemented, this is done 4 times in a row in different places...
The 4 stack-trace from the EntityManager ctor and up is below for documenation:
Code:
at org.hibernate.util.NamingHelper.getInitialContext(NamingHelper.java:27)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJTATransactionLookup.java:114)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJTATransactionLookup.java:108)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter.getTransaction(WebSphereExtendedJTATransactionLookup.java:82)
at org.hibernate.ejb.transaction.JoinableCMTTransaction.isTransactionInProgress(JoinableCMTTransaction.java:45)
at org.hibernate.ejb.transaction.JoinableCMTTransaction.tryJoiningTransaction(JoinableCMTTransaction.java:59)
at org.hibernate.ejb.transaction.JoinableCMTTransactionFactory.isTransactionInProgress(JoinableCMTTransactionFactory.java:27)
at org.hibernate.jdbc.JDBCContext.isTransactionInProgress(JDBCContext.java:187)
at org.hibernate.jdbc.JDBCContext.registerSynchronizationIfPossible(JDBCContext.java:159)
at org.hibernate.impl.SessionImpl.checkTransactionSynchStatus(SessionImpl.java:1867)
at org.hibernate.impl.SessionImpl.isOpen(SessionImpl.java:320)
at org.hibernate.ejb.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:463)
at org.hibernate.ejb.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:82)
at org.hibernate.ejb.EntityManagerImpl.<init>(EntityManagerImpl.java:37)
Code:
at org.hibernate.util.NamingHelper.getInitialContext(NamingHelper.java:27)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJTATransactionLookup.java:114)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJTATransactionLookup.java:108)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter.getTransaction(WebSphereExtendedJTATransactionLookup.java:82)
at org.hibernate.ejb.transaction.JoinableCMTTransaction.isTransactionInProgress(JoinableCMTTransaction.java:34)
at org.hibernate.ejb.transaction.JoinableCMTTransactionFactory.isTransactionInProgress(JoinableCMTTransactionFactory.java:28)
at org.hibernate.jdbc.JDBCContext.isTransactionInProgress(JDBCContext.java:187)
at org.hibernate.jdbc.JDBCContext.registerSynchronizationIfPossible(JDBCContext.java:159)
at org.hibernate.impl.SessionImpl.checkTransactionSynchStatus(SessionImpl.java:1867)
at org.hibernate.impl.SessionImpl.isOpen(SessionImpl.java:320)
at org.hibernate.ejb.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:463)
at org.hibernate.ejb.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:82)
at org.hibernate.ejb.EntityManagerImpl.<init>(EntityManagerImpl.java:37)
Code:
at org.hibernate.util.NamingHelper.getInitialContext(NamingHelper.java:27)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJTATransactionLookup.java:114)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJTATransactionLookup.java:108)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter.getTransaction(WebSphereExtendedJTATransactionLookup.java:82)
at org.hibernate.jdbc.JDBCContext.registerSynchronizationIfPossible(JDBCContext.java:164)
at org.hibernate.impl.SessionImpl.checkTransactionSynchStatus(SessionImpl.java:1867)
at org.hibernate.impl.SessionImpl.isOpen(SessionImpl.java:320)
at org.hibernate.ejb.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:463)
at org.hibernate.ejb.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:82)
at org.hibernate.ejb.EntityManagerImpl.<init>(EntityManagerImpl.java:37)
Code:
at org.hibernate.util.NamingHelper.getInitialContext(NamingHelper.java:27)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJTATransactionLookup.java:114)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJTATransactionLookup.java:108)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter.getTransaction(WebSphereExtendedJTATransactionLookup.java:82)
at org.hibernate.transaction.CMTTransaction.getTransaction(CMTTransaction.java:91)
at org.hibernate.transaction.CMTTransaction.registerSynchronization(CMTTransaction.java:156)
at org.hibernate.ejb.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:482)
at org.hibernate.ejb.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:82)
at org.hibernate.ejb.EntityManagerImpl.<init>(EntityManagerImpl.java:37)
Now, I've looked at the similar implementation in OpenJPA (0.9.6) that according to a post at
IBM DeveloperWorks is "done right".
In OpenJPA, the extended transaction support instance is basically only look'ed up once and then stored in a static (look at OpenJPA's AutomaticManagedRuntime and WASManagedRuntime for reference).
So, I've hacked the Hibernate (3-2-3) implementation of WebSphereExtendedJTATransactionLookup to bascially do the same...
The following lines (at about line 108) are changed in my "hacked" version of WebSphereExtendedJTATransactionLookup.
Code:
private static Object extendedJTATransaction;
public class TransactionAdapter implements Transaction {
private TransactionAdapter(Properties props) {
try {
if (extendedJTATransaction == null) {
extendedJTATransaction = NamingHelper.getInitialContext(props)
.lookup("java:comp/websphere/ExtendedJTATransaction");
}
}
catch (NamingException ne) {
throw new HibernateException(ne);
}
}
...
Basically the extendedJTATransaction is taken out as instance variable in the inner class TransactionAdapter and put as static in WebSphereExtendedJTATransactionLookup.
Now, it is only look'ed up once.
Kind Regards
Jesper Udby
Freelance I/T consultant
Denmark :-)