FileDocCategorySizeDatePackage
JDBCContext.javaAPI DocHibernate 3.2.510053Fri Sep 08 16:01:52 BST 2006org.hibernate.jdbc

JDBCContext

public class JDBCContext extends Object implements Serializable, ConnectionManager.Callback
Acts as the mediary between "entity-mode related" sessions in terms of their interaction with the JDBC data store.
author
Steve Ebersole

Fields Summary
private static final Log
log
private Context
owner
private ConnectionManager
connectionManager
private transient boolean
isTransactionCallbackRegistered
private transient org.hibernate.Transaction
hibernateTransaction
Constructors Summary
public JDBCContext(Context owner, Connection connection, org.hibernate.Interceptor interceptor)


	       
		this.owner = owner;
		this.connectionManager = new ConnectionManager(
		        owner.getFactory(),
		        this,
		        owner.getConnectionReleaseMode(),
		        connection,
		        interceptor
			);

		final boolean registerSynchronization = owner.isAutoCloseSessionEnabled()
		        || owner.isFlushBeforeCompletionEnabled()
		        || owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
		if ( registerSynchronization ) {
			registerSynchronizationIfPossible();
		}
	
private JDBCContext()
Private constructor used exclusively for custom serialization...

	
Methods Summary
public voidafterNontransactionalQuery(boolean success)
Called after executing a query outside the scope of a Hibernate or JTA transaction

		log.trace( "after autocommit" );
		try {
			// check to see if the connection is in auto-commit 
			// mode (no connection means aggressive connection
			// release outside a JTA transaction context, so MUST
			// be autocommit mode)
			boolean isAutocommit = connectionManager.isAutoCommit();

			connectionManager.afterTransaction();
			
			if ( isAutocommit ) {
				owner.afterTransactionCompletion(success, null);
			}
		}
		catch (SQLException sqle) {
			throw JDBCExceptionHelper.convert( 
					owner.getFactory().getSQLExceptionConverter(),
					sqle,
					"could not inspect JDBC autocommit mode"
				);
		}
	
public voidafterTransactionBegin(org.hibernate.Transaction tx)
We cannot rely upon this method being called! It is only called if we are using Hibernate Transaction API.

		log.trace( "after transaction begin" );
		owner.afterTransactionBegin(tx);
	
public voidafterTransactionCompletion(boolean success, org.hibernate.Transaction tx)

		log.trace( "after transaction completion" );

		if ( getFactory().getStatistics().isStatisticsEnabled() ) {
			getFactory().getStatisticsImplementor().endTransaction(success);
		}

		connectionManager.afterTransaction();

		isTransactionCallbackRegistered = false;
		hibernateTransaction = null;
		owner.afterTransactionCompletion(success, tx);
	
public voidbeforeTransactionCompletion(org.hibernate.Transaction tx)

		log.trace( "before transaction completion" );
		owner.beforeTransactionCompletion(tx);
	
public java.sql.ConnectionborrowConnection()

		return connectionManager.borrowConnection();
	
public java.sql.Connectionconnection()

		if ( owner.isClosed() ) {
			throw new SessionException( "Session is closed" );
		}

		return connectionManager.getConnection();
	
public voidconnectionCleanedUp()

		if ( !isTransactionCallbackRegistered ) {
			afterTransactionCompletion( false, null );
			// Note : success = false, because we don't know the outcome of the transaction
		}
	
public voidconnectionOpened()

		if ( owner.getFactory().getStatistics().isStatisticsEnabled() ) {
			owner.getFactory().getStatisticsImplementor().connect();
		}
	
public static org.hibernate.jdbc.JDBCContextdeserialize(java.io.ObjectInputStream ois, org.hibernate.jdbc.JDBCContext$Context context, org.hibernate.Interceptor interceptor)
Custom deserialization routine used during deserialization of a Session/PersistenceContext for increased performance.

param
ois The stream from which to read the entry.
throws
IOException

		JDBCContext jdbcContext = new JDBCContext();
		jdbcContext.owner = context;
		jdbcContext.connectionManager = ConnectionManager.deserialize(
				ois,
				context.getFactory(),
		        interceptor,
		        context.getConnectionReleaseMode(),
		        jdbcContext
		);
		return jdbcContext;
	
public ConnectionManagergetConnectionManager()

		return connectionManager;
	
public org.hibernate.engine.SessionFactoryImplementorgetFactory()

		return owner.getFactory();
	
public org.hibernate.TransactiongetTransaction()

		if (hibernateTransaction==null) {
			hibernateTransaction = owner.getFactory().getSettings()
					.getTransactionFactory()
					.createTransaction( this, owner );
		}
		return hibernateTransaction;
	
public booleanisTransactionInProgress()

		return owner.getFactory().getSettings().getTransactionFactory()
				.isTransactionInProgress( this, owner, hibernateTransaction );
	
private voidreadObject(java.io.ObjectInputStream ois)

		ois.defaultReadObject();
		isTransactionCallbackRegistered = ois.readBoolean();
	
public booleanregisterCallbackIfNecessary()

		if ( isTransactionCallbackRegistered ) {
			return false;
		}
		else {
			isTransactionCallbackRegistered = true;
			return true;
		}

	
public booleanregisterSynchronizationIfPossible()

		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.trace( "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 );
			}
		}
	
public voidserialize(java.io.ObjectOutputStream oos)
Custom serialization routine used during serialization of a Session/PersistenceContext for increased performance.

param
oos The stream to which we should write the serial data.
throws
IOException

		connectionManager.serialize( oos );
	
private voidwriteObject(java.io.ObjectOutputStream oos)

		// isTransactionCallbackRegistered denotes whether any Hibernate
		// Transaction has registered as a callback against this
		// JDBCContext; only one such callback is allowed.  Directly
		// serializing this value causes problems with JDBCTransaction,
		// or really any Transaction impl where the callback is local
		// to the Transaction instance itself, since that Transaction
		// is not serialized along with the JDBCContext.  Thus we
		// handle that fact here explicitly...
		oos.defaultWriteObject();
		boolean deserHasCallbackRegistered = isTransactionCallbackRegistered
				&& ! owner.getFactory().getSettings().getTransactionFactory()
				.areCallbacksLocalToHibernateTransactions();
		oos.writeBoolean( deserHasCallbackRegistered );