FileDocCategorySizeDatePackage
SQLQueryReturnProcessor.javaAPI DocHibernate 3.2.518259Thu Jun 15 00:21:06 BST 2006org.hibernate.loader.custom.sql

SQLQueryReturnProcessor

public class SQLQueryReturnProcessor extends Object
Responsible for processing the series of {@link org.hibernate.engine.query.sql.NativeSQLQueryReturn returns} defined by a {@link org.hibernate.engine.query.sql.NativeSQLQuerySpecification} and breaking them down into a series of {@link Return returns} for use within the {@link org.hibernate.loader.custom.CustomLoader}.
author
Gavin King
author
Max Andersen
author
Steve Ebersole

Fields Summary
public static final Log
log
private org.hibernate.engine.query.sql.NativeSQLQueryReturn[]
queryReturns
private final Map
alias2Return
private final Map
alias2OwnerAlias
private final Map
alias2Persister
private final Map
alias2Suffix
private final Map
alias2CollectionPersister
private final Map
alias2CollectionSuffix
private final Map
entityPropertyResultMaps
private final Map
collectionPropertyResultMaps
private final org.hibernate.engine.SessionFactoryImplementor
factory
private int
entitySuffixSeed
private int
collectionSuffixSeed
Constructors Summary
public SQLQueryReturnProcessor(org.hibernate.engine.query.sql.NativeSQLQueryReturn[] queryReturns, org.hibernate.engine.SessionFactoryImplementor factory)



	     
		this.queryReturns = queryReturns;
		this.factory = factory;
	
Methods Summary
private voidaddCollection(java.lang.String role, java.lang.String alias, java.util.Map propertyResults)

		SQLLoadableCollection collectionPersister = ( SQLLoadableCollection ) factory.getCollectionPersister( role );
		alias2CollectionPersister.put( alias, collectionPersister );
		String suffix = generateCollectionSuffix();
		log.trace( "mapping alias [" + alias + "] to collection-suffix [" + suffix + "]" );
		alias2CollectionSuffix.put( alias, suffix );
		collectionPropertyResultMaps.put( alias, propertyResults );

		if ( collectionPersister.isOneToMany() ) {
			SQLLoadable persister = ( SQLLoadable ) collectionPersister.getElementPersister();
			addPersister( alias, filter( propertyResults ), persister );
		}
	
private voidaddPersister(java.lang.String alias, java.util.Map propertyResult, org.hibernate.persister.entity.SQLLoadable persister)

param
propertyResult
param
persister

		alias2Persister.put( alias, persister );
		String suffix = generateEntitySuffix();
		log.trace( "mapping alias [" + alias + "] to entity-suffix [" + suffix + "]" );
		alias2Suffix.put( alias, suffix );
		entityPropertyResultMaps.put( alias, propertyResult );
	
private java.util.Mapfilter(java.util.Map propertyResults)

		Map result = new HashMap( propertyResults.size() );

		String keyPrefix = "element.";

		Iterator iter = propertyResults.entrySet().iterator();
		while ( iter.hasNext() ) {
			Map.Entry element = ( Map.Entry ) iter.next();
			String path = ( String ) element.getKey();
			if ( path.startsWith( keyPrefix ) ) {
				result.put( path.substring( keyPrefix.length() ), element.getValue() );
			}
		}

		return result;
	
private java.lang.StringgenerateCollectionSuffix()

		return collectionSuffixSeed++ + "__";
	
public java.util.ListgenerateCustomReturns(boolean queryHadAliases)

		List customReturns = new ArrayList();
		Map customReturnsByAlias = new HashMap();
		for ( int i = 0; i < queryReturns.length; i++ ) {
			if ( queryReturns[i] instanceof NativeSQLQueryScalarReturn ) {
				NativeSQLQueryScalarReturn rtn = ( NativeSQLQueryScalarReturn ) queryReturns[i];
				customReturns.add( new ScalarReturn( rtn.getType(), rtn.getColumnAlias() ) );
			}
			else if ( queryReturns[i] instanceof NativeSQLQueryRootReturn ) {
				NativeSQLQueryRootReturn rtn = ( NativeSQLQueryRootReturn ) queryReturns[i];
				String alias = rtn.getAlias();
				EntityAliases entityAliases;
				if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
					entityAliases = new DefaultEntityAliases(
							( Map ) entityPropertyResultMaps.get( alias ),
							( SQLLoadable ) alias2Persister.get( alias ),
							( String ) alias2Suffix.get( alias )
					);
				}
				else {
					entityAliases = new ColumnEntityAliases(
							( Map ) entityPropertyResultMaps.get( alias ),
							( SQLLoadable ) alias2Persister.get( alias ),
							( String ) alias2Suffix.get( alias )
					);
				}
				RootReturn customReturn = new RootReturn(
						alias,
						rtn.getReturnEntityName(),
						entityAliases,
						rtn.getLockMode()
				);
				customReturns.add( customReturn );
				customReturnsByAlias.put( rtn.getAlias(), customReturn );
			}
			else if ( queryReturns[i] instanceof NativeSQLQueryCollectionReturn ) {
				NativeSQLQueryCollectionReturn rtn = ( NativeSQLQueryCollectionReturn ) queryReturns[i];
				String alias = rtn.getAlias();
				SQLLoadableCollection persister = ( SQLLoadableCollection ) alias2CollectionPersister.get( alias );
				boolean isEntityElements = persister.getElementType().isEntityType();
				CollectionAliases collectionAliases;
				EntityAliases elementEntityAliases = null;
				if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
					collectionAliases = new GeneratedCollectionAliases(
							( Map ) collectionPropertyResultMaps.get( alias ),
							( SQLLoadableCollection ) alias2CollectionPersister.get( alias ),
							( String ) alias2CollectionSuffix.get( alias )
					);
					if ( isEntityElements ) {
						elementEntityAliases = new DefaultEntityAliases(
								( Map ) entityPropertyResultMaps.get( alias ),
								( SQLLoadable ) alias2Persister.get( alias ),
								( String ) alias2Suffix.get( alias )
						);
					}
				}
				else {
					collectionAliases = new ColumnCollectionAliases(
							( Map ) collectionPropertyResultMaps.get( alias ),
							( SQLLoadableCollection ) alias2CollectionPersister.get( alias )
					);
					if ( isEntityElements ) {
						elementEntityAliases = new ColumnEntityAliases(
								( Map ) entityPropertyResultMaps.get( alias ),
								( SQLLoadable ) alias2Persister.get( alias ),
								( String ) alias2Suffix.get( alias )
						);
					}
				}
				CollectionReturn customReturn = new CollectionReturn(
						alias,
						rtn.getOwnerEntityName(),
						rtn.getOwnerProperty(),
						collectionAliases,
				        elementEntityAliases,
						rtn.getLockMode()
				);
				customReturns.add( customReturn );
				customReturnsByAlias.put( rtn.getAlias(), customReturn );
			}
			else if ( queryReturns[i] instanceof NativeSQLQueryJoinReturn ) {
				NativeSQLQueryJoinReturn rtn = ( NativeSQLQueryJoinReturn ) queryReturns[i];
				String alias = rtn.getAlias();
				FetchReturn customReturn;
				NonScalarReturn ownerCustomReturn = ( NonScalarReturn ) customReturnsByAlias.get( rtn.getOwnerAlias() );
				if ( alias2CollectionPersister.containsKey( alias ) ) {
					SQLLoadableCollection persister = ( SQLLoadableCollection ) alias2CollectionPersister.get( alias );
					boolean isEntityElements = persister.getElementType().isEntityType();
					CollectionAliases collectionAliases;
					EntityAliases elementEntityAliases = null;
					if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
						collectionAliases = new GeneratedCollectionAliases(
								( Map ) collectionPropertyResultMaps.get( alias ),
								persister,
								( String ) alias2CollectionSuffix.get( alias )
						);
						if ( isEntityElements ) {
							elementEntityAliases = new DefaultEntityAliases(
									( Map ) entityPropertyResultMaps.get( alias ),
									( SQLLoadable ) alias2Persister.get( alias ),
									( String ) alias2Suffix.get( alias )
							);
						}
					}
					else {
						collectionAliases = new ColumnCollectionAliases(
								( Map ) collectionPropertyResultMaps.get( alias ),
								persister
						);
						if ( isEntityElements ) {
							elementEntityAliases = new ColumnEntityAliases(
									( Map ) entityPropertyResultMaps.get( alias ),
									( SQLLoadable ) alias2Persister.get( alias ),
									( String ) alias2Suffix.get( alias )
							);
						}
					}
					customReturn = new CollectionFetchReturn(
							alias,
							ownerCustomReturn,
							rtn.getOwnerProperty(),
							collectionAliases,
					        elementEntityAliases,
							rtn.getLockMode()
					);
				}
				else {
					EntityAliases entityAliases;
					if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
						entityAliases = new DefaultEntityAliases(
								( Map ) entityPropertyResultMaps.get( alias ),
								( SQLLoadable ) alias2Persister.get( alias ),
								( String ) alias2Suffix.get( alias )
						);
					}
					else {
						entityAliases = new ColumnEntityAliases(
								( Map ) entityPropertyResultMaps.get( alias ),
								( SQLLoadable ) alias2Persister.get( alias ),
								( String ) alias2Suffix.get( alias )
						);
					}
					customReturn = new EntityFetchReturn(
							alias,
							entityAliases,
							ownerCustomReturn,
							rtn.getOwnerProperty(),
							rtn.getLockMode()
					);
				}
				customReturns.add( customReturn );
				customReturnsByAlias.put( alias, customReturn );
			}
		}
		return customReturns;
	
private java.lang.StringgenerateEntitySuffix()

		return BasicLoader.generateSuffixes( entitySuffixSeed++, 1 )[0];
	
private org.hibernate.persister.entity.SQLLoadablegetSQLLoadable(java.lang.String entityName)

		EntityPersister persister = factory.getEntityPersister( entityName );
		if ( !(persister instanceof SQLLoadable) ) {
			throw new MappingException( "class persister is not SQLLoadable: " + entityName );
		}
		return (SQLLoadable) persister;
	
private booleanhasPropertyResultMap(java.lang.String alias)

		Map propertyMaps = internalGetPropertyResultsMap( alias );
		return propertyMaps != null && ! propertyMaps.isEmpty();
	
private java.util.MapinternalGetPropertyResultsMap(java.lang.String alias)

		NativeSQLQueryReturn rtn = ( NativeSQLQueryReturn ) alias2Return.get( alias );
		if ( rtn instanceof NativeSQLQueryNonScalarReturn ) {
			return ( ( NativeSQLQueryNonScalarReturn ) rtn ).getPropertyResultsMap();
		}
		else {
			return null;
		}
	
public org.hibernate.loader.custom.sql.SQLQueryReturnProcessor$ResultAliasContextprocess()

		// first, break down the returns into maps keyed by alias
		// so that role returns can be more easily resolved to their owners
		for ( int i = 0; i < queryReturns.length; i++ ) {
			if ( queryReturns[i] instanceof NativeSQLQueryNonScalarReturn ) {
				NativeSQLQueryNonScalarReturn rtn = ( NativeSQLQueryNonScalarReturn ) queryReturns[i];
				alias2Return.put( rtn.getAlias(), rtn );
				if ( rtn instanceof NativeSQLQueryJoinReturn ) {
					NativeSQLQueryJoinReturn fetchReturn = ( NativeSQLQueryJoinReturn ) rtn;
					alias2OwnerAlias.put( fetchReturn.getAlias(), fetchReturn.getOwnerAlias() );
				}
			}
		}

		// Now, process the returns
		for ( int i = 0; i < queryReturns.length; i++ ) {
			processReturn( queryReturns[i] );
		}

		return new ResultAliasContext();
	
private voidprocessCollectionReturn(org.hibernate.engine.query.sql.NativeSQLQueryCollectionReturn collectionReturn)

		// we are initializing an owned collection
		//collectionOwners.add( new Integer(-1) );
//		collectionOwnerAliases.add( null );
		String role = collectionReturn.getOwnerEntityName() + '." + collectionReturn.getOwnerProperty();
		addCollection(
				role,
				collectionReturn.getAlias(),
				collectionReturn.getPropertyResultsMap()
		);
	
private voidprocessJoinReturn(org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn fetchReturn)

		String alias = fetchReturn.getAlias();
//		if ( alias2Persister.containsKey( alias ) || collectionAliases.contains( alias ) ) {
		if ( alias2Persister.containsKey( alias ) || alias2CollectionPersister.containsKey( alias ) ) {
			// already been processed...
			return;
		}

		String ownerAlias = fetchReturn.getOwnerAlias();

		// Make sure the owner alias is known...
		if ( !alias2Return.containsKey( ownerAlias ) ) {
			throw new HibernateException( "Owner alias [" + ownerAlias + "] is unknown for alias [" + alias + "]" );
		}

		// If this return's alias has not been processed yet, do so b4 further processing of this return
		if ( !alias2Persister.containsKey( ownerAlias ) ) {
			NativeSQLQueryNonScalarReturn ownerReturn = ( NativeSQLQueryNonScalarReturn ) alias2Return.get(ownerAlias);
			processReturn( ownerReturn );
		}

		SQLLoadable ownerPersister = ( SQLLoadable ) alias2Persister.get( ownerAlias );
		Type returnType = ownerPersister.getPropertyType( fetchReturn.getOwnerProperty() );

		if ( returnType.isCollectionType() ) {
			String role = ownerPersister.getEntityName() + '." + fetchReturn.getOwnerProperty();
			addCollection( role, alias, fetchReturn.getPropertyResultsMap() );
//			collectionOwnerAliases.add( ownerAlias );
		}
		else if ( returnType.isEntityType() ) {
			EntityType eType = ( EntityType ) returnType;
			String returnEntityName = eType.getAssociatedEntityName();
			SQLLoadable persister = getSQLLoadable( returnEntityName );
			addPersister( alias, fetchReturn.getPropertyResultsMap(), persister );
		}

	
private voidprocessReturn(org.hibernate.engine.query.sql.NativeSQLQueryReturn rtn)

		if ( rtn instanceof NativeSQLQueryScalarReturn ) {
			processScalarReturn( ( NativeSQLQueryScalarReturn ) rtn );
		}
		else if ( rtn instanceof NativeSQLQueryRootReturn ) {
			processRootReturn( ( NativeSQLQueryRootReturn ) rtn );
		}
		else if ( rtn instanceof NativeSQLQueryCollectionReturn ) {
			processCollectionReturn( ( NativeSQLQueryCollectionReturn ) rtn );
		}
		else {
			processJoinReturn( ( NativeSQLQueryJoinReturn ) rtn );
		}
	
private voidprocessRootReturn(org.hibernate.engine.query.sql.NativeSQLQueryRootReturn rootReturn)

		if ( alias2Persister.containsKey( rootReturn.getAlias() ) ) {
			// already been processed...
			return;
		}

		SQLLoadable persister = getSQLLoadable( rootReturn.getReturnEntityName() );
		addPersister( rootReturn.getAlias(), rootReturn.getPropertyResultsMap(), persister );
	
private voidprocessScalarReturn(org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn typeReturn)

//		scalarColumnAliases.add( typeReturn.getColumnAlias() );
//		scalarTypes.add( typeReturn.getType() );