Hi experts,
We are using Websphere 6.0.2 application server with Hibernate 3.2.0.
I tried simple application scenario where I used one CMT stateless session bean with Hibernate as a DAO layer.
I configured everything according to the documentation (CMT, JTA, Websphere6 recommendations), exactly in hibernate.cfg.xml:
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</property>
<property name="hibernate.transaction.flush_before_completion">true</property>
<property name="hibernate.transaction.auto_close_session">true</property>
I don't use any transactional or session management code in my bean implementation.
There is only one SessionFactory created as a singleton and in every bean method I obtain only currentSession() instance of Session.
Of course the bean is configured in deployment descriptor as CMT stateless session bean and every method has 'Required' transaction attribute.
I expected that container would handle session and transaction tasks correctly (openning session, commiting transaction, flushing and closing session after transaction completion etc.)
There are some code snippets for your better imagination:
Code:
public class SimpleCounterBean implements javax.ejb.SessionBean
{
private HibernateSessionFactory hsf = null; // HibernateSessionFactory is singleton wrapper over org.hibernate.SessionFactory
.
.
.
public void ejbCreate() throws javax.ejb.CreateException
{
hsf = HibernateSessionFactory.getInstance();
.
.
.
public void increase()
{
Session s = hsf.getSession(); // calls on wrapped SessionFactory method getCurrentSession() only
SimpleCounterDTO cnt = (SimpleCounterDTO)s.load(SimpleCounterDTO.class,new Long(0));
cnt.setValue(cnt.getValue()+1);
}
.
.
.
When I ran this example I discovered strange behaviour in Hibernate's CMT session management.
Exactly (I had to add few log statements in Hibernate) in org.hibernate.context.JTASessionContext where SessionImpl was created, registered to currentSessionMap with transaction as a key and unregistered from currentSessionMap after transaction completion I discovered that unregistration of SessionImpl from currentSessionMap didn't happen.
Here is the trace log (org.hibernate.*=ALL):
.
.
.
[13.3.2007 14:50:54:531 CET] 00000053 SessionImpl 1 org.hibernate.impl.SessionImpl <init> opened session at timestamp: 11737938543
[13.3.2007 14:50:54:547 CET] 00000053 JTASessionCon 1 org.hibernate.context.JTASessionContext$CleanupSynch <init> new CleanupSynch,
txn=org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter@1e
[13.3.2007 14:50:54:547 CET] 00000053 JTASessionCon 1 org.hibernate.context.JTASessionContext currentSession session put to map,
txn=org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter@1e, currentSession=SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[]
collectionRemovals=[] collectionUpdates=[]])
[13.3.2007 14:50:54:547 CET] 00000053 JTASessionCon 1 org.hibernate.context.JTASessionContext currentSession
sessions=1.
. some hibernate logs
.
.
. and automatic flushing and closing session after transaction completion is ok
.
[13.3.2007 14:50:55:156 CET] 00000053 SessionImpl 3 org.hibernate.impl.SessionImpl managedClose automatically closing session
[13.3.2007 14:50:55:156 CET] 00000053 SessionImpl 3 org.hibernate.impl.SessionImpl close closing session
[13.3.2007 14:50:55:156 CET] 00000053 ConnectionMan 3 org.hibernate.jdbc.ConnectionManager cleanup connection already null in cleanup : no action
.
.
but.
[13.3.2007 14:50:55:156 CET] 00000053 JTASessionCon 1 org.hibernate.context.JTASessionContext$CleanupSynch afterCompletion session removed from map,
txn=org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter@0[13.3.2007 14:50:55:156 CET] 00000053 JTASessionCon 1 org.hibernate.context.JTASessionContext$CleanupSynch afterCompletion
sessions=1.
.
session remains in map.
SessionImpl remains in currentSessionMap and leads to leak.
Because I'm not expert in transactional management in WebSphere i can't identify the problem.
I only see that the transaction (as the key in map) is changed and doesn't match the key in currentSessionMap.
The currentSessionMap still growing.
Is there anybody who detects leak in similar scenario?
[/code]