alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (LoadContexts.java)

This example Hibernate source code file (LoadContexts.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

collection, collectionkey, collectionloadcontext, collectionloadcontext, constructing, coremessagelogger, entityloadcontext, entityloadcontext, io, jdbc, loadcontexts, loadingcollectionentry, loadingcollectionentry, map, map, persistencecontext, sql, util

The Hibernate LoadContexts.java source code

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.hibernate.engine.loading.internal;

import java.io.Serializable;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.jboss.logging.Logger;

import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.IdentityMap;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.pretty.MessageHelper;

/**
 * Maps {@link ResultSet result-sets} to specific contextual data
 * related to processing that {@link ResultSet result-sets}.
 * <p/>
 * 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.
 * <p/>
 * 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
 */
public class LoadContexts {

    private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, LoadContexts.class.getName());

	private final PersistenceContext persistenceContext;
	private Map<ResultSet,CollectionLoadContext> collectionLoadContexts;
	private Map<ResultSet,EntityLoadContext> entityLoadContexts;

	private Map<CollectionKey,LoadingCollectionEntry> xrefLoadingCollectionEntries;

	/**
	 * Creates and binds this to the given persistence context.
	 *
	 * @param persistenceContext The persistence context to which this
	 * will be bound.
	 */
	public LoadContexts(PersistenceContext persistenceContext) {
		this.persistenceContext = persistenceContext;
	}

	/**
	 * Retrieves the persistence context to which this is bound.
	 *
	 * @return The persistence context to which this is bound.
	 */
	public PersistenceContext getPersistenceContext() {
		return persistenceContext;
	}

	private SessionImplementor getSession() {
		return getPersistenceContext().getSession();
	}


	// cleanup code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 	/**
	 * Release internal state associated with the given result set.
	 * <p/>
	 * 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.
	 */
	public void cleanup(ResultSet resultSet) {
		if ( collectionLoadContexts != null ) {
			CollectionLoadContext collectionLoadContext = collectionLoadContexts.remove( resultSet );
			collectionLoadContext.cleanup();
		}
		if ( entityLoadContexts != null ) {
			EntityLoadContext entityLoadContext = entityLoadContexts.remove( resultSet );
			entityLoadContext.cleanup();
		}
	}

	/**
	 * Release internal state associated with *all* result sets.
	 * <p/>
	 * This is intended as a "failsafe" process to make sure we get everything
	 * cleaned up and released.
	 */
	public void cleanup() {
		if ( collectionLoadContexts != null ) {
			for ( CollectionLoadContext collectionLoadContext : collectionLoadContexts.values() ) {
				LOG.failSafeCollectionsCleanup( collectionLoadContext );
				collectionLoadContext.cleanup();
			}
			collectionLoadContexts.clear();
		}
		if ( entityLoadContexts != null ) {
			for ( EntityLoadContext entityLoadContext : entityLoadContexts.values() ) {
				LOG.failSafeEntitiesCleanup( entityLoadContext );
				entityLoadContext.cleanup();
			}
			entityLoadContexts.clear();
		}
	}


	// Collection load contexts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	/**
	 * Do we currently have any internal entries corresponding to loading
	 * collections?
	 *
	 * @return True if we currently hold state pertaining to loading collections;
	 * false otherwise.
	 */
	public boolean hasLoadingCollectionEntries() {
		return ( collectionLoadContexts != null && !collectionLoadContexts.isEmpty() );
	}

	/**
	 * Do we currently have any registered internal entries corresponding to loading
	 * collections?
	 *
	 * @return True if we currently hold state pertaining to a registered loading collections;
	 * false otherwise.
	 */
	public boolean hasRegisteredLoadingCollectionEntries() {
		return ( xrefLoadingCollectionEntries != null && !xrefLoadingCollectionEntries.isEmpty() );
	}


	/**
	 * 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.
	 */
	public CollectionLoadContext getCollectionLoadContext(ResultSet resultSet) {
		CollectionLoadContext context = null;
        if ( collectionLoadContexts == null ) {
			collectionLoadContexts = IdentityMap.instantiate( 8 );
		}
        else {
			context = 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;
	}

	/**
	 * 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.
	 */
	public PersistentCollection locateLoadingCollection(CollectionPersister persister, Serializable ownerKey) {
		LoadingCollectionEntry lce = locateLoadingCollectionEntry( new CollectionKey( persister, ownerKey ) );
		if ( lce != null ) {
            if ( LOG.isTraceEnabled() ) {
				LOG.tracef(
						"Returning loading collection: %s",
						MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() )
				);
			}
			return lce.getCollection();
		}
        // TODO : should really move this log statement to CollectionType, where this is used from...
        if ( LOG.isTraceEnabled() ) {
			LOG.tracef(
					"Creating collection wrapper: %s",
					MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() )
			);
		}
        return null;
	}

	// loading collection xrefs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	/**
	 * Register a loading collection xref.
	 * <p/>
	 * 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.
	 * <p/>
	 * 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
	 */
	void registerLoadingCollectionXRef(CollectionKey entryKey, LoadingCollectionEntry entry) {
		if ( xrefLoadingCollectionEntries == null ) {
			xrefLoadingCollectionEntries = new HashMap<CollectionKey,LoadingCollectionEntry>();
		}
		xrefLoadingCollectionEntries.put( entryKey, entry );
	}

	/**
	 * The inverse of {@link #registerLoadingCollectionXRef}.  Here, we are done
	 * processing the said collection entry, so we remove it from the
	 * load context.
	 * <p/>
	 * 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.
	 * <p/>
	 * 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.
	 */
	void unregisterLoadingCollectionXRef(CollectionKey key) {
		if ( !hasRegisteredLoadingCollectionEntries() ) {
			return;
		}
		xrefLoadingCollectionEntries.remove(key);
	 }

	/*package*/Map getLoadingCollectionXRefs() {
 		return xrefLoadingCollectionEntries;
 	}


	/**
	 * Locate the LoadingCollectionEntry within *any* of the tracked
	 * {@link CollectionLoadContext}s.
	 * <p/>
	 * 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.
	 */
	LoadingCollectionEntry locateLoadingCollectionEntry(CollectionKey key) {
        if (xrefLoadingCollectionEntries == null) return null;
        LOG.trace("Attempting to locate loading collection entry [" + key + "] in any result-set context");
		LoadingCollectionEntry rtn = xrefLoadingCollectionEntries.get( key );
        if (rtn == null) LOG.trace("Collection [" + key + "] not located in load context");
        else LOG.trace("Collection [" + key + "] located in load context");
		return rtn;
	}

	/*package*/void cleanupCollectionXRefs(Set<CollectionKey> entryKeys) {
		for ( CollectionKey entryKey : entryKeys ) {
			xrefLoadingCollectionEntries.remove( entryKey );
		}
	}


	// Entity load contexts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// 	* currently, not yet used...

	public EntityLoadContext getEntityLoadContext(ResultSet resultSet) {
		EntityLoadContext context = null;
		if ( entityLoadContexts == null ) {
			entityLoadContexts = IdentityMap.instantiate( 8 );
		}
		else {
			context = entityLoadContexts.get( resultSet );
		}
		if ( context == null ) {
			context = new EntityLoadContext( this, resultSet );
			entityLoadContexts.put( resultSet, context );
		}
		return context;
	}
}

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate LoadContexts.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.