FileDocCategorySizeDatePackage
LoadContexts.javaAPI DocHibernate 3.2.510393Thu Jun 07 13:22:50 BST 2007org.hibernate.engine.loading

LoadContexts

public class LoadContexts extends Object
Maps {@link ResultSet result-sets} to specific contextual data related to processing that {@link ResultSet result-sets}.

Implementation note: internally an {@link IdentityMap} is used to maintain the mappings; {@link IdentityMap} was chosen because I'd rather not be dependent upon potentially bad {@link ResultSet#equals} and {ResultSet#hashCode} implementations.

Considering the JDBC-redesign work, would further like this contextual info not mapped seperately, but available based on the result set being processed. This would also allow maintaining a single mapping as we could reliably get notification of the result-set closing...

author
Steve Ebersole

Fields Summary
private static final Log
log
private final org.hibernate.engine.PersistenceContext
persistenceContext
private Map
collectionLoadContexts
private Map
entityLoadContexts
private Map
xrefLoadingCollectionEntries
Constructors Summary
public LoadContexts(org.hibernate.engine.PersistenceContext persistenceContext)
Creates and binds this to the given persistence context.

param
persistenceContext The persistence context to which this will be bound.


	                    	 
	   
		this.persistenceContext = persistenceContext;
	
Methods Summary
public voidcleanup(java.sql.ResultSet resultSet)
Release internal state associated with the given result set.

This should be called when we are done with processing said result set, ideally as the result set is being closed.

param
resultSet The result set for which it is ok to release associated resources.

		if ( collectionLoadContexts != null ) {
			CollectionLoadContext collectionLoadContext = ( CollectionLoadContext ) collectionLoadContexts.remove( resultSet );
			collectionLoadContext.cleanup();
		}
		if ( entityLoadContexts != null ) {
			EntityLoadContext entityLoadContext = ( EntityLoadContext ) entityLoadContexts.remove( resultSet );
			entityLoadContext.cleanup();
		}
	
public voidcleanup()
Release internal state associated with *all* result sets.

This is intended as a "failsafe" process to make sure we get everything cleaned up and released.

		if ( collectionLoadContexts != null ) {
			Iterator itr = collectionLoadContexts.values().iterator();
			while ( itr.hasNext() ) {
				CollectionLoadContext collectionLoadContext = ( CollectionLoadContext ) itr.next();
				log.warn( "fail-safe cleanup (collections) : " + collectionLoadContext );
				collectionLoadContext.cleanup();
			}
			collectionLoadContexts.clear();
		}
		if ( entityLoadContexts != null ) {
			Iterator itr = entityLoadContexts.values().iterator();
			while ( itr.hasNext() ) {
				EntityLoadContext entityLoadContext = ( EntityLoadContext ) itr.next();
				log.warn( "fail-safe cleanup (entities) : " + entityLoadContext );
				entityLoadContext.cleanup();
			}
			entityLoadContexts.clear();
		}
	
voidcleanupCollectionXRefs(java.util.Set entryKeys)

		Iterator itr = entryKeys.iterator();
		while ( itr.hasNext() ) {
			final CollectionKey entryKey = ( CollectionKey ) itr.next();
			xrefLoadingCollectionEntries.remove( entryKey );
		}
	
public CollectionLoadContextgetCollectionLoadContext(java.sql.ResultSet resultSet)
Get the {@link CollectionLoadContext} associated with the given {@link ResultSet}, creating one if needed.

param
resultSet The result set for which to retrieve the context.
return
The processing context.

		CollectionLoadContext context = null;
		if ( collectionLoadContexts == null ) {
			collectionLoadContexts = IdentityMap.instantiate( 8 );
		}
		else {
			context = ( CollectionLoadContext ) collectionLoadContexts.get( resultSet );
		}
		if ( context == null ) {
			if ( log.isTraceEnabled() ) {
				log.trace( "constructing collection load context for result set [" + resultSet + "]" );
			}
			context = new CollectionLoadContext( this, resultSet );
			collectionLoadContexts.put( resultSet, context );
		}
		return context;
	
public EntityLoadContextgetEntityLoadContext(java.sql.ResultSet resultSet)

		EntityLoadContext context = null;
		if ( entityLoadContexts == null ) {
			entityLoadContexts = IdentityMap.instantiate( 8 );
		}
		else {
			context = ( EntityLoadContext ) entityLoadContexts.get( resultSet );
		}
		if ( context == null ) {
			context = new EntityLoadContext( this, resultSet );
			entityLoadContexts.put( resultSet, context );
		}
		return context;
	
private org.hibernate.EntityModegetEntityMode()

		return getSession().getEntityMode();
	
java.util.MapgetLoadingCollectionXRefs()

 		return xrefLoadingCollectionEntries;
 	
public org.hibernate.engine.PersistenceContextgetPersistenceContext()
Retrieves the persistence context to which this is bound.

return
The persistence context to which this is bound.

		return persistenceContext;
	
private org.hibernate.engine.SessionImplementorgetSession()

		return getPersistenceContext().getSession();
	
public booleanhasLoadingCollectionEntries()
Do we currently have any internal entries corresponding to loading collections?

return
True if we currently hold state pertaining to loading collections; false otherwise.

		return ( xrefLoadingCollectionEntries != null && !xrefLoadingCollectionEntries.isEmpty() );
	
public org.hibernate.collection.PersistentCollectionlocateLoadingCollection(org.hibernate.persister.collection.CollectionPersister persister, java.io.Serializable ownerKey)
Attempt to locate the loading collection given the owner's key. The lookup here occurs against all result-set contexts...

param
persister The collection persister
param
ownerKey The owner key
return
The loading collection, or null if not found.

		LoadingCollectionEntry lce = locateLoadingCollectionEntry( new CollectionKey( persister, ownerKey, getEntityMode() ) );
		if ( lce != null ) {
			if ( log.isTraceEnabled() ) {
				log.trace( "returning loading collection:" + MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() ) );
			}
			return lce.getCollection();
		}
		else {
			// todo : should really move this log statement to CollectionType, where this is used from...
			if ( log.isTraceEnabled() ) {
				log.trace( "creating collection wrapper:" + MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() ) );
			}
			return null;
		}
	
LoadingCollectionEntrylocateLoadingCollectionEntry(org.hibernate.engine.CollectionKey key)
Locate the LoadingCollectionEntry within *any* of the tracked {@link CollectionLoadContext}s.

Implementation note: package protected, as this is meant solely for use by {@link CollectionLoadContext} to be able to locate collections being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.

param
key The collection key.
return
The located entry; or null.

		if ( xrefLoadingCollectionEntries == null ) {
			return null;
		}
		if ( log.isTraceEnabled() ) {
			log.trace( "attempting to locate loading collection entry [" + key + "] in any result-set context" );
		}
		LoadingCollectionEntry rtn = ( LoadingCollectionEntry ) xrefLoadingCollectionEntries.get( key );
		if ( log.isTraceEnabled() ) {
			if ( rtn == null ) {
				log.trace( "collection [" + key + "] located in load context" );
			}
			else {
				log.trace( "collection [" + key + "] not located in load context" );
			}
		}
		return rtn;
	
voidregisterLoadingCollectionXRef(org.hibernate.engine.CollectionKey entryKey, LoadingCollectionEntry entry)
Register a loading collection xref.

This xref map is used because sometimes a collection is in process of being loaded from one result set, but needs to be accessed from the context of another "nested" result set processing.

Implementation note: package protected, as this is meant solely for use by {@link CollectionLoadContext} to be able to locate collections being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.

param
entryKey The xref collection key
param
entry The corresponding loading collection entry

		if ( xrefLoadingCollectionEntries == null ) {
			xrefLoadingCollectionEntries = new HashMap();
		}
		xrefLoadingCollectionEntries.put( entryKey, entry );
	
voidunregisterLoadingCollectionXRef(org.hibernate.engine.CollectionKey key)
The inverse of {@link #registerLoadingCollectionXRef}. Here, we are done processing the said collection entry, so we remove it from the load context.

The idea here is that other loading collections can now reference said collection directly from the {@link PersistenceContext} because it has completed its load cycle.

Implementation note: package protected, as this is meant solely for use by {@link CollectionLoadContext} to be able to locate collections being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.

param
key The key of the collection we are done processing.

		if ( !hasLoadingCollectionEntries() ) {
			return;
		}
		xrefLoadingCollectionEntries.remove(key);