FileDocCategorySizeDatePackage
TwoPhaseLoad.javaAPI DocHibernate 3.2.58687Wed Mar 15 12:15:18 GMT 2006org.hibernate.engine

TwoPhaseLoad

public final class TwoPhaseLoad extends Object
Functionality relating to Hibernate's two-phase loading process, that may be reused by persisters that do not use the Loader framework
author
Gavin King

Fields Summary
private static final Log
log
Constructors Summary
private TwoPhaseLoad()

	
	  
Methods Summary
public static voidaddUninitializedCachedEntity(EntityKey key, java.lang.Object object, org.hibernate.persister.entity.EntityPersister persister, org.hibernate.LockMode lockMode, boolean lazyPropertiesAreUnfetched, java.lang.Object version, SessionImplementor session)

		session.getPersistenceContext().addEntity(
				object, 
				Status.LOADING, 
				null, 
				key, 
				version, 
				lockMode, 
				true, 
				persister, 
				false, 
				lazyPropertiesAreUnfetched
			);
	
public static voidaddUninitializedEntity(EntityKey key, java.lang.Object object, org.hibernate.persister.entity.EntityPersister persister, org.hibernate.LockMode lockMode, boolean lazyPropertiesAreUnfetched, SessionImplementor session)
Add an uninitialized instance of an entity class, as a placeholder to ensure object identity. Must be called before postHydrate(). Create a "temporary" entry for a newly instantiated entity. The entity is uninitialized, but we need the mapping from id to instance in order to guarantee uniqueness.

		session.getPersistenceContext().addEntity(
				object, 
				Status.LOADING, 
				null, 
				key, 
				null, 
				lockMode, 
				true, 
				persister, 
				false, 
				lazyPropertiesAreUnfetched
			);
	
public static voidinitializeEntity(java.lang.Object entity, boolean readOnly, SessionImplementor session, org.hibernate.event.PreLoadEvent preLoadEvent, org.hibernate.event.PostLoadEvent postLoadEvent)
Perform the second step of 2-phase load. Fully initialize the entity instance. After processing a JDBC result set, we "resolve" all the associations between the entities which were instantiated and had their state "hydrated" into an array

		
		//TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)
	
		final PersistenceContext persistenceContext = session.getPersistenceContext();
		EntityEntry entityEntry = persistenceContext.getEntry(entity);
		if ( entityEntry == null ) {
			throw new AssertionFailure( "possible non-threadsafe access to the session" );
		}
		EntityPersister persister = entityEntry.getPersister();
		Serializable id = entityEntry.getId();
		Object[] hydratedState = entityEntry.getLoadedState();
	
		if ( log.isDebugEnabled() )
			log.debug(
					"resolving associations for " +
					MessageHelper.infoString(persister, id, session.getFactory())
				);
	
		Type[] types = persister.getPropertyTypes();
		for ( int i = 0; i < hydratedState.length; i++ ) {
			final Object value = hydratedState[i];
			if ( value!=LazyPropertyInitializer.UNFETCHED_PROPERTY && value!=BackrefPropertyAccessor.UNKNOWN ) {
				hydratedState[i] = types[i].resolve( value, session, entity );
			}
		}
	
		//Must occur after resolving identifiers!
		if ( session.isEventSource() ) {
			preLoadEvent.setEntity(entity).setState(hydratedState).setId(id).setPersister(persister);
			PreLoadEventListener[] listeners = session.getListeners().getPreLoadEventListeners();
			for ( int i = 0; i < listeners.length; i++ ) {
				listeners[i].onPreLoad(preLoadEvent);
			}
		}
	
		persister.setPropertyValues( entity, hydratedState, session.getEntityMode() );
	
		final SessionFactoryImplementor factory = session.getFactory();
		if ( persister.hasCache() && session.getCacheMode().isPutEnabled() ) {
			
			if ( log.isDebugEnabled() )
				log.debug(
						"adding entity to second-level cache: " +
						MessageHelper.infoString( persister, id, session.getFactory() )
					);

			Object version = Versioning.getVersion(hydratedState, persister);
			CacheEntry entry = new CacheEntry(
					hydratedState, 
					persister, 
					entityEntry.isLoadedWithLazyPropertiesUnfetched(), 
					version, 
					session, 
					entity
				);
			CacheKey cacheKey = new CacheKey( 
					id, 
					persister.getIdentifierType(), 
					persister.getRootEntityName(), 
					session.getEntityMode(), 
					session.getFactory() 
				);
			boolean put = persister.getCache().put( 
					cacheKey, 
					persister.getCacheEntryStructure().structure(entry), 
					session.getTimestamp(),
					version, 
					persister.isVersioned() ?
							persister.getVersionType().getComparator() : 
							null,
					useMinimalPuts(session, entityEntry)
				); //we could use persister.hasLazyProperties() instead of true
	
			if ( put && factory.getStatistics().isStatisticsEnabled() ) {
				factory.getStatisticsImplementor().secondLevelCachePut( persister.getCache().getRegionName() );
			}
		}
	
		if ( readOnly || !persister.isMutable() ) {
			//no need to take a snapshot - this is a 
			//performance optimization, but not really
			//important, except for entities with huge 
			//mutable property values
			persistenceContext.setEntryStatus(entityEntry, Status.READ_ONLY);
		}
		else {
			//take a snapshot
			TypeFactory.deepCopy( 
					hydratedState, 
					persister.getPropertyTypes(), 
					persister.getPropertyUpdateability(), 
					hydratedState,  //after setting values to object, entityMode
					session
				);
			persistenceContext.setEntryStatus(entityEntry, Status.MANAGED);
		}
		
		persister.afterInitialize(
				entity, 
				entityEntry.isLoadedWithLazyPropertiesUnfetched(), 
				session
			);
		
		if ( session.isEventSource() ) {
			postLoadEvent.setEntity(entity).setId(id).setPersister(persister);
			PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
			for ( int i = 0; i < listeners.length; i++ ) {
				listeners[i].onPostLoad(postLoadEvent);
			}
		}
		
		if ( log.isDebugEnabled() )
			log.debug(
					"done materializing entity " +
					MessageHelper.infoString( persister, id, session.getFactory() )
				);
		
		if ( factory.getStatistics().isStatisticsEnabled() ) {
			factory.getStatisticsImplementor().loadEntity( persister.getEntityName() );
		}
	
	
public static voidpostHydrate(org.hibernate.persister.entity.EntityPersister persister, java.io.Serializable id, java.lang.Object[] values, java.lang.Object rowId, java.lang.Object object, org.hibernate.LockMode lockMode, boolean lazyPropertiesAreUnfetched, SessionImplementor session)
Register the "hydrated" state of an entity instance, after the first step of 2-phase loading. Add the "hydrated state" (an array) of an uninitialized entity to the session. We don't try to resolve any associations yet, because there might be other entities waiting to be read from the JDBC result set we are currently processing

		
		Object version = Versioning.getVersion(values, persister);
		session.getPersistenceContext().addEntry( 
				object, 
				Status.LOADING,
				values, 
				rowId, 
				id, 
				version, 
				lockMode, 
				true, 
				persister, 
				false, 
				lazyPropertiesAreUnfetched 
			);
	
		if ( log.isTraceEnabled() && version!=null ) {
			String versionStr = persister.isVersioned()
					? persister.getVersionType().toLoggableString( version, session.getFactory() )
			        : "null";
			log.trace( "Version: " + versionStr );
		}
	
	
private static booleanuseMinimalPuts(SessionImplementor session, EntityEntry entityEntry)

		return ( session.getFactory().getSettings().isMinimalPutsEnabled() && 
						session.getCacheMode()!=CacheMode.REFRESH ) ||
				( entityEntry.getPersister().hasLazyProperties() && 
						entityEntry.isLoadedWithLazyPropertiesUnfetched() && 
						entityEntry.getPersister().isLazyPropertiesCacheable() );