FileDocCategorySizeDatePackage
CustomLoader.javaAPI DocHibernate 3.2.520371Thu Jul 06 07:21:30 BST 2006org.hibernate.loader.custom

CustomLoader

public class CustomLoader extends org.hibernate.loader.Loader
Extension point for loaders which use a SQL result set with "unexpected" column aliases.
author
Gavin King
author
Steve Ebersole

(Omit source code)

Fields Summary
private final String
sql
private final Set
querySpaces
private final Map
namedParameterBindPoints
private final org.hibernate.persister.entity.Queryable[]
entityPersisters
private final int[]
entiytOwners
private final org.hibernate.loader.EntityAliases[]
entityAliases
private final org.hibernate.persister.collection.QueryableCollection[]
collectionPersisters
private final int[]
collectionOwners
private final org.hibernate.loader.CollectionAliases[]
collectionAliases
private final org.hibernate.LockMode[]
lockModes
private final ResultRowProcessor
rowProcessor
private org.hibernate.type.Type[]
resultTypes
private String[]
transformerAliases
Constructors Summary
public CustomLoader(CustomQuery customQuery, org.hibernate.engine.SessionFactoryImplementor factory)



	     
		super( factory );

		this.sql = customQuery.getSQL();
		this.querySpaces.addAll( customQuery.getQuerySpaces() );
		this.namedParameterBindPoints = customQuery.getNamedParameterBindPoints();

		List entityPersisters = new ArrayList();
		List entityOwners = new ArrayList();
		List entityAliases = new ArrayList();

		List collectionPersisters = new ArrayList();
		List collectionOwners = new ArrayList();
		List collectionAliases = new ArrayList();

		List lockModes = new ArrayList();
		List resultColumnProcessors = new ArrayList();
		List nonScalarReturnList = new ArrayList();
		List resultTypes = new ArrayList();
		List specifiedAliases = new ArrayList();
		int returnableCounter = 0;
		boolean hasScalars = false;

		Iterator itr = customQuery.getCustomQueryReturns().iterator();
		while ( itr.hasNext() ) {
			final Return rtn = ( Return ) itr.next();
			if ( rtn instanceof ScalarReturn ) {
				ScalarReturn scalarRtn = ( ScalarReturn ) rtn;
				resultTypes.add( scalarRtn.getType() );
				specifiedAliases.add( scalarRtn.getColumnAlias() );
				resultColumnProcessors.add(
						new ScalarResultColumnProcessor(
								scalarRtn.getColumnAlias(),
								scalarRtn.getType()
						)
				);
				hasScalars = true;
			}
			else if ( rtn instanceof RootReturn ) {
				RootReturn rootRtn = ( RootReturn ) rtn;
				Queryable persister = ( Queryable ) factory.getEntityPersister( rootRtn.getEntityName() );
				entityPersisters.add( persister );
				lockModes.add( rootRtn.getLockMode() );
				resultColumnProcessors.add( new NonScalarResultColumnProcessor( returnableCounter++ ) );
				nonScalarReturnList.add( rtn );
				entityOwners.add( new Integer( -1 ) );
				resultTypes.add( persister.getType() );
				specifiedAliases.add( rootRtn.getAlias() );
				entityAliases.add( rootRtn.getEntityAliases() );
				ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );
			}
			else if ( rtn instanceof CollectionReturn ) {
				CollectionReturn collRtn = ( CollectionReturn ) rtn;
				String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty();
				QueryableCollection persister = ( QueryableCollection ) factory.getCollectionPersister( role );
				collectionPersisters.add( persister );
				lockModes.add( collRtn.getLockMode() );
				resultColumnProcessors.add( new NonScalarResultColumnProcessor( returnableCounter++ ) );
				nonScalarReturnList.add( rtn );
				collectionOwners.add( new Integer( -1 ) );
				resultTypes.add( persister.getType() );
				specifiedAliases.add( collRtn.getAlias() );
				collectionAliases.add( collRtn.getCollectionAliases() );
				// determine if the collection elements are entities...
				Type elementType = persister.getElementType();
				if ( elementType.isEntityType() ) {
					Queryable elementPersister = ( Queryable ) ( ( EntityType ) elementType ).getAssociatedJoinable( factory );
					entityPersisters.add( elementPersister );
					entityOwners.add( new Integer( -1 ) );
					entityAliases.add( collRtn.getElementEntityAliases() );
					ArrayHelper.addAll( querySpaces, elementPersister.getQuerySpaces() );
				}
			}
			else if ( rtn instanceof EntityFetchReturn ) {
				EntityFetchReturn fetchRtn = ( EntityFetchReturn ) rtn;
				NonScalarReturn ownerDescriptor = fetchRtn.getOwner();
				int ownerIndex = nonScalarReturnList.indexOf( ownerDescriptor );
				entityOwners.add( new Integer( ownerIndex ) );
				lockModes.add( fetchRtn.getLockMode() );
				Queryable ownerPersister = determineAppropriateOwnerPersister( ownerDescriptor );
				EntityType fetchedType = ( EntityType ) ownerPersister.getPropertyType( fetchRtn.getOwnerProperty() );
				String entityName = fetchedType.getAssociatedEntityName( getFactory() );
				Queryable persister = ( Queryable ) factory.getEntityPersister( entityName );
				entityPersisters.add( persister );
				nonScalarReturnList.add( rtn );
				specifiedAliases.add( fetchRtn.getAlias() );
				entityAliases.add( fetchRtn.getEntityAliases() );
				ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );
			}
			else if ( rtn instanceof CollectionFetchReturn ) {
				CollectionFetchReturn fetchRtn = ( CollectionFetchReturn ) rtn;
				NonScalarReturn ownerDescriptor = fetchRtn.getOwner();
				int ownerIndex = nonScalarReturnList.indexOf( ownerDescriptor );
				collectionOwners.add( new Integer( ownerIndex ) );
				lockModes.add( fetchRtn.getLockMode() );
				Queryable ownerPersister = determineAppropriateOwnerPersister( ownerDescriptor );
				String role = ownerPersister.getEntityName() + '." + fetchRtn.getOwnerProperty();
				QueryableCollection persister = ( QueryableCollection ) factory.getCollectionPersister( role );
				collectionPersisters.add( persister );
				nonScalarReturnList.add( rtn );
				specifiedAliases.add( fetchRtn.getAlias() );
				collectionAliases.add( fetchRtn.getCollectionAliases() );
				// determine if the collection elements are entities...
				Type elementType = persister.getElementType();
				if ( elementType.isEntityType() ) {
					Queryable elementPersister = ( Queryable ) ( ( EntityType ) elementType ).getAssociatedJoinable( factory );
					entityPersisters.add( elementPersister );
					entityOwners.add( new Integer( ownerIndex ) );
					entityAliases.add( fetchRtn.getElementEntityAliases() );
					ArrayHelper.addAll( querySpaces, elementPersister.getQuerySpaces() );
				}
			}
			else {
				throw new HibernateException( "unexpected custom query return type : " + rtn.getClass().getName() );
			}
		}

		this.entityPersisters = new Queryable[ entityPersisters.size() ];
		for ( int i = 0; i < entityPersisters.size(); i++ ) {
			this.entityPersisters[i] = ( Queryable ) entityPersisters.get( i );
		}
		this.entiytOwners = ArrayHelper.toIntArray( entityOwners );
		this.entityAliases = new EntityAliases[ entityAliases.size() ];
		for ( int i = 0; i < entityAliases.size(); i++ ) {
			this.entityAliases[i] = ( EntityAliases ) entityAliases.get( i );
		}

		this.collectionPersisters = new QueryableCollection[ collectionPersisters.size() ];
		for ( int i = 0; i < collectionPersisters.size(); i++ ) {
			this.collectionPersisters[i] = ( QueryableCollection ) collectionPersisters.get( i );
		}
		this.collectionOwners = ArrayHelper.toIntArray( collectionOwners );
		this.collectionAliases = new CollectionAliases[ collectionAliases.size() ];
		for ( int i = 0; i < collectionAliases.size(); i++ ) {
			this.collectionAliases[i] = ( CollectionAliases ) collectionAliases.get( i );
		}

		this.lockModes = new LockMode[ lockModes.size() ];
		for ( int i = 0; i < lockModes.size(); i++ ) {
			this.lockModes[i] = ( LockMode ) lockModes.get( i );
		}

		this.resultTypes = ArrayHelper.toTypeArray( resultTypes );
		this.transformerAliases = ArrayHelper.toStringArray( specifiedAliases );

		this.rowProcessor = new ResultRowProcessor(
				hasScalars,
		        ( ResultColumnProcessor[] ) resultColumnProcessors.toArray( new ResultColumnProcessor[ resultColumnProcessors.size() ] )
		);
	
Methods Summary
protected voidautoDiscoverTypes(java.sql.ResultSet rs)

		try {
			Metadata metadata = new Metadata( getFactory(), rs );
			List aliases = new ArrayList();
			List types = new ArrayList();

			rowProcessor.prepareForAutoDiscovery( metadata );

			for ( int i = 0; i < rowProcessor.columnProcessors.length; i++ ) {
				rowProcessor.columnProcessors[i].performDiscovery( metadata, types, aliases );
			}

			resultTypes = ArrayHelper.toTypeArray( types );
			transformerAliases = ArrayHelper.toStringArray( aliases );
		}
		catch ( SQLException e ) {
			throw new HibernateException( "Exception while trying to autodiscover types.", e );
		}
	
private org.hibernate.persister.entity.QueryabledetermineAppropriateOwnerPersister(NonScalarReturn ownerDescriptor)

		String entityName = null;
		if ( ownerDescriptor instanceof RootReturn ) {
			entityName = ( ( RootReturn ) ownerDescriptor ).getEntityName();
		}
		else if ( ownerDescriptor instanceof CollectionReturn ) {
			CollectionReturn collRtn = ( CollectionReturn ) ownerDescriptor;
			String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty();
			CollectionPersister persister = getFactory().getCollectionPersister( role );
			EntityType ownerType = ( EntityType ) persister.getElementType();
			entityName = ownerType.getAssociatedEntityName( getFactory() );
		}
		else if ( ownerDescriptor instanceof FetchReturn ) {
			FetchReturn fetchRtn = ( FetchReturn ) ownerDescriptor;
			Queryable persister = determineAppropriateOwnerPersister( fetchRtn.getOwner() );
			Type ownerType = persister.getPropertyType( fetchRtn.getOwnerProperty() );
			if ( ownerType.isEntityType() ) {
				entityName = ( ( EntityType ) ownerType ).getAssociatedEntityName( getFactory() );
			}
			else if ( ownerType.isCollectionType() ) {
				Type ownerCollectionElementType = ( ( CollectionType ) ownerType ).getElementType( getFactory() );
				if ( ownerCollectionElementType.isEntityType() ) {
					entityName = ( ( EntityType ) ownerCollectionElementType ).getAssociatedEntityName( getFactory() );
				}
			}
		}

		if ( entityName == null ) {
			throw new HibernateException( "Could not determine fetch owner : " + ownerDescriptor );
		}

		return ( Queryable ) getFactory().getEntityPersister( entityName );
	
protected org.hibernate.loader.CollectionAliases[]getCollectionAliases()

		return collectionAliases;
	
protected int[]getCollectionOwners()

		return collectionOwners;
	
protected org.hibernate.persister.collection.CollectionPersister[]getCollectionPersisters()

		return collectionPersisters;
	
protected org.hibernate.loader.EntityAliases[]getEntityAliases()

		return entityAliases;
	
protected org.hibernate.persister.entity.Loadable[]getEntityPersisters()

		return entityPersisters;
	
private static org.hibernate.hql.HolderInstantiatorgetHolderInstantiator(org.hibernate.transform.ResultTransformer resultTransformer, java.lang.String[] queryReturnAliases)

		if ( resultTransformer != null ) {
			return HolderInstantiator.NOOP_INSTANTIATOR;
		}
		else {
			return new HolderInstantiator(resultTransformer, queryReturnAliases);
		}
	
protected org.hibernate.LockMode[]getLockModes(java.util.Map lockModesMap)

		return lockModes;
	
public int[]getNamedParameterLocs(java.lang.String name)

		Object loc = namedParameterBindPoints.get( name );
		if ( loc == null ) {
			throw new QueryException(
					"Named parameter does not appear in Query: " + name,
					sql
			);
		}
		if ( loc instanceof Integer ) {
			return new int[] { ( ( Integer ) loc ).intValue() };
		}
		else {
			return ArrayHelper.toIntArray( ( List ) loc );
		}
	
protected int[]getOwners()

		return entiytOwners;
	
protected java.lang.StringgetQueryIdentifier()

		return sql;
	
public java.util.SetgetQuerySpaces()

		return querySpaces;
	
protected java.lang.ObjectgetResultColumnOrRow(java.lang.Object[] row, org.hibernate.transform.ResultTransformer transformer, java.sql.ResultSet rs, org.hibernate.engine.SessionImplementor session)

		return rowProcessor.buildResultRow( row, rs, transformer != null, session );
	
protected java.util.ListgetResultList(java.util.List results, org.hibernate.transform.ResultTransformer resultTransformer)

		// meant to handle dynamic instantiation queries...(Copy from QueryLoader)
		HolderInstantiator holderInstantiator = HolderInstantiator.getHolderInstantiator(
				null,
				resultTransformer,
				getReturnAliasesForTransformer()
		);
		if ( holderInstantiator.isRequired() ) {
			for ( int i = 0; i < results.size(); i++ ) {
				Object[] row = ( Object[] ) results.get( i );
				Object result = holderInstantiator.instantiate(row);
				results.set( i, result );
			}
			
			return resultTransformer.transformList(results);
		}
		else {
			return results;
		}
	
private java.lang.String[]getReturnAliasesForTransformer()

		return transformerAliases;
	
protected java.lang.StringgetSQLString()

		return sql;
	
public java.util.Listlist(org.hibernate.engine.SessionImplementor session, org.hibernate.engine.QueryParameters queryParameters)

		return list( session, queryParameters, querySpaces, resultTypes );
	
public org.hibernate.ScrollableResultsscroll(org.hibernate.engine.QueryParameters queryParameters, org.hibernate.engine.SessionImplementor session)

		
		return scroll(
				queryParameters,
				resultTypes,
				getHolderInstantiator( queryParameters.getResultTransformer(), getReturnAliasesForTransformer() ),
				session
		);