-->
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.  [ 3 posts ] 
Author Message
 Post subject: Sessions and transactions Hibernate Wiki entry
PostPosted: Wed Oct 18, 2006 1:28 pm 
Newbie

Joined: Wed Oct 18, 2006 12:30 pm
Posts: 8
I just read the Wiki entry on "Sessions and transactions" http://www.hibernate.org/42.html

In section "Transaction demarcation with JTA" the second code example raises the question whether it is really correct:

Code:
// code from the Hibernate wiki

UserTransaction tx = (UserTransaction)new InitialContext()
                            .lookup("java:comp/UserTransaction");

Session session = factory.openSession();

try {
    tx.begin();

    // Do some work
    session.load(...);
    session.persist(...);

    session.flush();

    tx.commit();
}
catch (RuntimeException e) {
    tx.rollback();
    throw e; // or display error message
}
finally {
    session.close();
}


In this example the Hibernate session is managed by the programmer himself. The pattern is comparable to the use of an application-managed entity manager with JPA. With JPA an application-managed entity manager created inside a transaction will automatically synchronize its persistence context with the transaction. By contrast, an application-managed entity manager created outside of a transaction needs to explicitly join the JTA transaction by calling joinTransaction() on the EntityManager interface.

This (or something similar) is not done in above Hibernate example however.

My question therefore: Is above Hibernate example taken from the Wiki really correct? How does the Hibernate session become aware of the transaction which began after the session had been created already?

A clarification would be highly appreciated.


Compare how it would look like with JPA:

Code:
// comparable pattern with JPA

@Stateful
public class JPAExampleBean {
   @PersistenceUnit(unitName="xxx")
   EntityManagerFactory emf;
   EntityManager  em;

   public void init() {

      // application-managed EntityManager created outside of a transaction
      em = emf.createEntityManager();
      ...
   }

 
   public void persistSomeEntity(Entity e) {
     // as the EntityManager was created outside of a transaction,
     // we need to call em.joinTransaction(); in order to synchronize
     // the persistence context with the database when the transaction
     // commits.

     em.joinTransaction();
     em.persist(e);
     ...
   }

   ... more methods of the StateFul Session Bean...

  @Remove
  public void finish () {
   ...
  }

}


Top
 Profile  
 
 Post subject: Re: Sessions and transactions Hibernate Wiki entry
PostPosted: Wed Oct 18, 2006 3:31 pm 
Newbie

Joined: Wed Oct 18, 2006 12:30 pm
Posts: 8
WolleS wrote:
My question therefore: Is above Hibernate example taken from the Wiki really correct? How does the Hibernate session become aware of the transaction which began after the session had been created already?



Can it be that the flush() method binds the session to the JTA transaction if the session has not been bound already?


In class org.hibernate.impl.SessionImpl the flush() method calls checkTransactionSynchStatus();
Code:
public void flush() throws HibernateException {
      errorIfClosed();
      checkTransactionSynchStatus();
                ...
   }


checkTransactionSynchStatus() in turn is implemented as follows

Code:
private void checkTransactionSynchStatus() {
      if ( jdbcContext != null && !isClosed() ) {
         jdbcContext.registerSynchronizationIfPossible();
      }
   }



This looks as if checkTransactionSynchStatus() tries some sort of sychronization registration.


Unfortunately, my understanding of the internals is still very limited. And the Javadocs for jdbcContext.registerSynchronizationIfPossible() are empty.



That being said, it would be positive if it was better documented how a session created manually outside of a transaction gets bound to a JTA transaction.


Any Hibernate expert can comment on this?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 18, 2006 3:42 pm 
Newbie

Joined: Wed Oct 18, 2006 12:30 pm
Posts: 8
I do not have much knowledge about it, but it certainly looks to me as if registerSynchronizationIfPossible() binds the session (or better JDBC resource) to the JTA transaction.

This would mean that the Hibernate example from the WIKI would be correct.

Would be good anyway if this important binding behavior could be documented.




Code:
package org.hibernate.jdbc;


public class JDBCContext {

   public boolean registerSynchronizationIfPossible() {
      if ( isTransactionCallbackRegistered ) {
         // we already have a callback registered; either a local
         // (org.hibernate.Transaction) transaction has accepted
         // callback responsibilities, or we have previously
         // registered a transaction synch.
         return true;
      }
      boolean localCallbacksOnly = owner.getFactory().getSettings()
            .getTransactionFactory()
            .areCallbacksLocalToHibernateTransactions();
      if ( localCallbacksOnly ) {
         // the configured transaction-factory says it only supports
         // local callback mode, so no sense attempting to register a
         // JTA Synchronization
         return false;
      }
      TransactionManager tm = owner.getFactory().getTransactionManager();
      if ( tm == null ) {
         // if there is no TM configured, we will not be able to access
         // the javax.transaction.Transaction object in order to
         // register a synch anyway.
         return false;
      }
      else {
         try {
            if ( !isTransactionInProgress() ) {
               log.debug( "TransactionFactory reported no active transaction; Synchronization not registered" );
               return false;
            }
            else {
               javax.transaction.Transaction tx = tm.getTransaction();
               if ( JTAHelper.isMarkedForRollback( tx ) ) {
                  log.debug( "Transaction is marked for rollback; skipping Synchronization registration" );
                  return false;
               }
               else {
                  tx.registerSynchronization( new CacheSynchronization(owner, this, tx, null) );
                  isTransactionCallbackRegistered = true;
                  log.debug("successfully registered Synchronization");
                  return true;
               }
            }
         }
         catch( HibernateException e ) {
            throw e;
         }
         catch (Exception e) {
            throw new TransactionException( "could not register synchronization with JTA TransactionManager", e );
         }
      }
   }


...
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.