-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: JTASessionContext not removing session with WebSphere
PostPosted: Tue May 30, 2006 10:14 am 
Newbie

Joined: Tue May 30, 2006 9:23 am
Posts: 1
Hi

The JTASessionContext implementation does not remove the session at the end of the transaction with WebSphere appserver 6.

After looking into this a found that the transaction is stored as the key with the session in a map.
The transaction is not immutable and therefore when it wants to remove the session using the transaction it does not find a match.
I'm not sure if this only happens with WebSphere.

I have changed the JTASessionContext as follows to use the hashcode as the key and then it removes the session correctly:
Code:
public class JTASessionContext implements CurrentSessionContext {

   private static final Log log = LogFactory.getLog( JTASessionContext.class );

   protected final SessionFactoryImplementor factory;
   private transient Map currentSessionMap = new Hashtable();

   public JTASessionContext(SessionFactoryImplementor factory) {
      this.factory = factory;
   }

   public Session currentSession() throws HibernateException {
      TransactionManager transactionManager = factory.getTransactionManager();
      if ( transactionManager == null ) {
         throw new HibernateException( "No TransactionManagerLookup specified" );
      }

      Transaction txn = null;
      try {
         txn = transactionManager.getTransaction();
         if ( txn == null ) {
            throw new HibernateException( "Unable to locate current JTA transaction" );
         }
         if ( !JTAHelper.isInProgress( txn.getStatus() ) ) {
            // We could register the session against the transaction even though it is
            // not started, but we'd have no guarentee of ever getting the map
            // entries cleaned up (aside from spawning threads).
            throw new HibernateException( "Current transaction is not in progress" );
         }
      }
      catch ( HibernateException e ) {
         throw e;
      }
      catch ( Throwable t ) {
         throw new HibernateException( "Problem locating/validating JTA transaction", t );
      }
      
      Integer key = new Integer(txn.hashCode());
      Session currentSession = ( Session ) currentSessionMap.get( key );

      if ( currentSession == null ) {
         currentSession = buildOrObtainSession();

         try {
            txn.registerSynchronization( buildCleanupSynch( txn ) );
         }
         catch ( Throwable t ) {
            try {
               currentSession.close();
            }
            catch ( Throwable ignore ) {
               log.debug( "Unable to release generated current-session on failed synch registration", ignore );
            }
            throw new HibernateException( "Unable to register cleanup Synchronization with TransactionManager" );
         }

         currentSessionMap.put( key, currentSession );
      }

      return currentSession;
   }

   private CleanupSynch buildCleanupSynch(Transaction txn) {
      return new CleanupSynch( new Integer(txn.hashCode()), this );
   }

   /**
    * Strictly provided for subclassing purposes; specifically to allow long-session
    * support.
    * <p/>
    * This implementation always just opens a new session.
    *
    * @return the built or (re)obtained session.
    */
   protected Session buildOrObtainSession() {
      return factory.openSession(
            null,
              isAutoFlushEnabled(),
              isAutoCloseEnabled(),
              getConnectionReleaseMode()
         );
   }

   /**
    * Mainly for subclass usage.  This impl always returns true.
    *
    * @return Whether or not the the session should be closed by transaction completion.
    */
   protected boolean isAutoCloseEnabled() {
      return true;
   }

   /**
    * Mainly for subclass usage.  This impl always returns true.
    *
    * @return Whether or not the the session should be flushed prior transaction completion.
    */
   protected boolean isAutoFlushEnabled() {
      return true;
   }

   /**
    * Mainly for subclass usage.  This impl always returns after_statement.
    *
    * @return The connection release mode for any built sessions.
    */
   protected ConnectionReleaseMode getConnectionReleaseMode() {
      return ConnectionReleaseMode.AFTER_STATEMENT;
   }

   /**
    * JTA transaction synch used for cleanup of the internal session map.
    */
   protected static class CleanupSynch implements Synchronization {
      
      private Integer transactionKey;
      private JTASessionContext context;

      public CleanupSynch(Integer transactionKey, JTASessionContext context) {
         this.transactionKey = transactionKey;
         this.context = context;
      }

      public void beforeCompletion() {
      }

      public void afterCompletion(int i) {
         context.currentSessionMap.remove( transactionKey );
      }
   }
}


Hibernate version:
3.1.3

Application server:
WebSphere 6

Database:
Oracle 10G
[/b][/code]


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 30, 2006 12:24 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
http://opensource.atlassian.com/project ... e/HHH-1786

And yes this does only happen in WebSphere because of their "wonderful" JTA "abstractions".


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.