FileDocCategorySizeDatePackage
QueryTranslatorImpl.javaAPI DocHibernate 3.2.533992Tue Jan 23 09:31:14 GMT 2007org.hibernate.hql.classic

QueryTranslatorImpl

public class QueryTranslatorImpl extends org.hibernate.loader.BasicLoader implements org.hibernate.hql.FilterTranslator
An instance of QueryTranslator translates a Hibernate query string to SQL.

Fields Summary
private static final String[]
NO_RETURN_ALIASES
private final String
queryIdentifier
private final String
queryString
private final Map
typeMap
private final Map
collections
private List
returnedTypes
private final List
fromTypes
private final List
scalarTypes
private final Map
namedParameters
private final Map
aliasNames
private final Map
oneToOneOwnerNames
private final Map
uniqueKeyOwnerReferences
private final Map
decoratedPropertyMappings
private final List
scalarSelectTokens
private final List
whereTokens
private final List
havingTokens
private final Map
joins
private final List
orderByTokens
private final List
groupByTokens
private final Set
querySpaces
private final Set
entitiesToFetch
private final Map
pathAliases
private final Map
pathJoins
private org.hibernate.persister.entity.Queryable[]
persisters
private int[]
owners
private org.hibernate.type.EntityType[]
ownerAssociationTypes
private String[]
names
private boolean[]
includeInSelect
private int
selectLength
private org.hibernate.type.Type[]
returnTypes
private org.hibernate.type.Type[]
actualReturnTypes
private String[]
scalarColumnNames
private Map
tokenReplacements
private int
nameCount
private int
parameterCount
private boolean
distinct
private boolean
compiled
private String
sqlString
private Class
holderClass
private Constructor
holderConstructor
private boolean
hasScalars
private boolean
shallowQuery
private QueryTranslatorImpl
superQuery
private org.hibernate.persister.collection.QueryableCollection
collectionPersister
private int
collectionOwnerColumn
private String
collectionOwnerName
private String
fetchName
private String[]
suffixes
private Map
enabledFilters
private static final Log
log
Constructors Summary
public QueryTranslatorImpl(String queryIdentifier, String queryString, Map enabledFilters, org.hibernate.engine.SessionFactoryImplementor factory)
Construct a query translator

param
queryIdentifier A unique identifier for the query of which this translation is part; typically this is the original, user-supplied query string.
param
queryString The "preprocessed" query string; at the very least already processed by {@link org.hibernate.hql.QuerySplitter}.
param
enabledFilters Any enabled filters.
param
factory The session factory.


	                                                   	 
	 
			 
	         
	         
	          
		super( factory );
		this.queryIdentifier = queryIdentifier;
		this.queryString = queryString;
		this.enabledFilters = enabledFilters;
	
public QueryTranslatorImpl(String queryString, Map enabledFilters, org.hibernate.engine.SessionFactoryImplementor factory)
Construct a query translator; this form used internally.

param
queryString The query string to process.
param
enabledFilters Any enabled filters.
param
factory The session factory.

		this( queryString, queryString, enabledFilters, factory );
	
Methods Summary
voidaddCollection(java.lang.String name, java.lang.String role)

		collections.put( name, role );
	
voidaddEntityToFetch(java.lang.String name, java.lang.String oneToOneOwnerName, org.hibernate.type.AssociationType ownerAssociationType)

		addEntityToFetch( name );
		if ( oneToOneOwnerName != null ) oneToOneOwnerNames.put( name, oneToOneOwnerName );
		if ( ownerAssociationType != null ) uniqueKeyOwnerReferences.put( name, ownerAssociationType );
	
private voidaddEntityToFetch(java.lang.String name)

		entitiesToFetch.add( name );
	
voidaddFrom(java.lang.String name, java.lang.String type, org.hibernate.engine.JoinSequence joinSequence)

		addType( name, type );
		addFrom( name, joinSequence );
	
voidaddFrom(java.lang.String name, org.hibernate.engine.JoinSequence joinSequence)

		fromTypes.add( name );
		addJoin( name, joinSequence );
	
private voidaddFromAssociation(java.lang.String elementName, java.lang.String collectionRole)
Used for collection filters

		//q.addCollection(collectionName, collectionRole);
		QueryableCollection persister = getCollectionPersister( collectionRole );
		Type collectionElementType = persister.getElementType();
		if ( !collectionElementType.isEntityType() ) {
			throw new QueryException( "collection of values in filter: " + elementName );
		}

		String[] keyColumnNames = persister.getKeyColumnNames();
		//if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole);

		String collectionName;
		JoinSequence join = new JoinSequence( getFactory() );
		collectionName = persister.isOneToMany() ?
				elementName :
				createNameForCollection( collectionRole );
		join.setRoot( persister, collectionName );
		if ( !persister.isOneToMany() ) {
			//many-to-many
			addCollection( collectionName, collectionRole );
			try {
				join.addJoin( ( AssociationType ) persister.getElementType(),
						elementName,
						JoinFragment.INNER_JOIN,
						persister.getElementColumnNames(collectionName) );
			}
			catch ( MappingException me ) {
				throw new QueryException( me );
			}
		}
		join.addCondition( collectionName, keyColumnNames, " = ?" );
		//if ( persister.hasWhere() ) join.addCondition( persister.getSQLWhereString(collectionName) );
		EntityType elemType = ( EntityType ) collectionElementType;
		addFrom( elementName, elemType.getAssociatedEntityName(), join );

	
voidaddFromClass(java.lang.String name, org.hibernate.persister.entity.Queryable classPersister)

		JoinSequence joinSequence = new JoinSequence( getFactory() )
				.setRoot( classPersister, name );
		//crossJoins.add(name);
		addFrom( name, classPersister.getEntityName(), joinSequence );
	
voidaddFromCollection(java.lang.String name, java.lang.String collectionRole, org.hibernate.engine.JoinSequence joinSequence)

		//register collection role
		addCollection( name, collectionRole );
		addJoin( name, joinSequence );
	
voidaddFromJoinOnly(java.lang.String name, org.hibernate.engine.JoinSequence joinSequence)

		addJoin( name, joinSequence.getFromPart() );
	
voidaddJoin(java.lang.String name, org.hibernate.engine.JoinSequence joinSequence)

		if ( !joins.containsKey( name ) ) joins.put( name, joinSequence );
	
voidaddNamedParameter(java.lang.String name)

		if ( superQuery != null ) superQuery.addNamedParameter( name );
		Integer loc = new Integer( parameterCount++ );
		Object o = namedParameters.get( name );
		if ( o == null ) {
			namedParameters.put( name, loc );
		}
		else if ( o instanceof Integer ) {
			ArrayList list = new ArrayList( 4 );
			list.add( o );
			list.add( loc );
			namedParameters.put( name, list );
		}
		else {
			( ( ArrayList ) o ).add( loc );
		}
	
voidaddPathAliasAndJoin(java.lang.String path, java.lang.String alias, org.hibernate.engine.JoinSequence joinSequence)

		pathAliases.put( path, alias );
		pathJoins.put( path, joinSequence );
	
voidaddQuerySpaces(java.io.Serializable[] spaces)

		for ( int i = 0; i < spaces.length; i++ ) {
			querySpaces.add( spaces[i] );
		}
		if ( superQuery != null ) superQuery.addQuerySpaces( spaces );
	
voidaddSelectClass(java.lang.String name)

		returnedTypes.add( name );
	
voidaddSelectScalar(org.hibernate.type.Type type)

		scalarTypes.add( type );
	
voidaddType(java.lang.String name, java.lang.String type)

		typeMap.put( name, type );
	
voidappendGroupByToken(java.lang.String token)

		groupByTokens.add( token );
	
voidappendHavingToken(java.lang.String token)

		havingTokens.add( token );
	
voidappendOrderByToken(java.lang.String token)

		orderByTokens.add( token );
	
voidappendScalarSelectToken(java.lang.String token)

		scalarSelectTokens.add( token );
	
voidappendScalarSelectTokens(java.lang.String[] tokens)

		scalarSelectTokens.add( tokens );
	
voidappendWhereToken(java.lang.String token)

		whereTokens.add( token );
	
protected java.lang.StringapplyLocks(java.lang.String sql, java.util.Map lockModes, org.hibernate.dialect.Dialect dialect)

		// can't cache this stuff either (per-invocation)
		final String result;
		if ( lockModes == null || lockModes.size() == 0 ) {
			result = sql;
		}
		else {
			Map aliasedLockModes = new HashMap();
			Iterator iter = lockModes.entrySet().iterator();
			while ( iter.hasNext() ) {
				Map.Entry me = ( Map.Entry ) iter.next();
				aliasedLockModes.put( getAliasName( ( String ) me.getKey() ), me.getValue() );
			}
			Map keyColumnNames = null;
			if ( dialect.forUpdateOfColumns() ) {
				keyColumnNames = new HashMap();
				for ( int i = 0; i < names.length; i++ ) {
					keyColumnNames.put( names[i], persisters[i].getIdentifierColumnNames() );
				}
			}
			result = dialect.applyLocksToSql( sql, aliasedLockModes, keyColumnNames );
		}
		logQuery( queryString, result );
		return result;
	
public java.util.ListcollectSqlStrings()

		return ArrayHelper.toList( new String[] { sqlString } );
	
voidcompile(org.hibernate.hql.classic.QueryTranslatorImpl superquery)
Compile a subquery.

param
superquery The containing query of the query to be compiled.
throws
org.hibernate.MappingException Indicates problems resolving things referenced in the query.
throws
org.hibernate.QueryException Generally some form of syntatic failure.

		this.tokenReplacements = superquery.tokenReplacements;
		this.superQuery = superquery;
		this.shallowQuery = true;
		this.enabledFilters = superquery.getEnabledFilters();
		compile();
	
public synchronized voidcompile(java.util.Map replacements, boolean scalar)
Compile a "normal" query. This method may be called multiple times. Subsequent invocations are no-ops.

		if ( !compiled ) {
			this.tokenReplacements = replacements;
			this.shallowQuery = scalar;
			compile();
		}
	
public synchronized voidcompile(java.lang.String collectionRole, java.util.Map replacements, boolean scalar)
Compile a filter. This method may be called multiple times. Subsequent invocations are no-ops.


		if ( !isCompiled() ) {
			addFromAssociation( "this", collectionRole );
			compile( replacements, scalar );
		}
	
private voidcompile()
Compile the query (generate the SQL).

throws
org.hibernate.MappingException Indicates problems resolving things referenced in the query.
throws
org.hibernate.QueryException Generally some form of syntatic failure.


		log.trace( "compiling query" );
		try {
			ParserHelper.parse( new PreprocessingParser( tokenReplacements ),
					queryString,
					ParserHelper.HQL_SEPARATORS,
					this );
			renderSQL();
		}
		catch ( QueryException qe ) {
			qe.setQueryString( queryString );
			throw qe;
		}
		catch ( MappingException me ) {
			throw me;
		}
		catch ( Exception e ) {
			log.debug( "unexpected query compilation problem", e );
			e.printStackTrace();
			QueryException qe = new QueryException( "Incorrect query syntax", e );
			qe.setQueryString( queryString );
			throw qe;
		}

		postInstantiate();

		compiled = true;

	
public booleancontainsCollectionFetches()

		return false;
	
java.lang.StringcreateNameFor(java.lang.String type)

		return StringHelper.generateAlias( type, nextCount() );
	
java.lang.StringcreateNameForCollection(java.lang.String role)

		return StringHelper.generateAlias( role, nextCount() );
	
voiddecoratePropertyMapping(java.lang.String name, org.hibernate.persister.entity.PropertyMapping mapping)

		decoratedPropertyMappings.put( name, mapping );
	
public intexecuteUpdate(org.hibernate.engine.QueryParameters queryParameters, org.hibernate.engine.SessionImplementor session)

		throw new UnsupportedOperationException( "Not supported!  Use the AST translator...");
	
public java.lang.StringgetAliasName(java.lang.String alias)

		String name = ( String ) aliasNames.get( alias );
		if ( name == null ) {
			if ( superQuery != null ) {
				name = superQuery.getAliasName( alias );
			}
			else {
				name = alias;
			}
		}
		return name;
	
protected java.lang.String[]getAliases()

		return names;
	
protected int[]getCollectionOwners()

		return new int[] { collectionOwnerColumn };
	
org.hibernate.persister.collection.QueryableCollectiongetCollectionPersister(java.lang.String role)

		try {
			return ( QueryableCollection ) getFactory().getCollectionPersister( role );
		}
		catch ( ClassCastException cce ) {
			throw new QueryException( "collection role is not queryable: " + role );
		}
		catch ( Exception e ) {
			throw new QueryException( "collection role not found: " + role );
		}
	
public org.hibernate.persister.collection.CollectionPersister[]getCollectionPersisters()
Overrides method from Loader

		return collectionPersister == null ? null : new CollectionPersister[] { collectionPersister };
	
protected java.lang.String[]getCollectionSuffixes()

		return collectionPersister == null ? null : new String[] { "__" };
	
public java.lang.String[][]getColumnNames()

		return scalarColumnNames;
	
private org.hibernate.persister.entity.PropertyMappinggetDecoratedPropertyMapping(java.lang.String name)

		return ( PropertyMapping ) decoratedPropertyMappings.get( name );
	
public java.util.MapgetEnabledFilters()

		return enabledFilters;
	
org.hibernate.persister.entity.QueryablegetEntityPersister(java.lang.String entityName)

		try {
			return ( Queryable ) getFactory().getEntityPersister( entityName );
		}
		catch ( Exception e ) {
			throw new QueryException( "persistent class not found: " + entityName );
		}
	
private org.hibernate.persister.entity.QueryablegetEntityPersisterForName(java.lang.String name)

		String type = getType( name );
		Queryable persister = getEntityPersister( type );
		if ( persister == null ) throw new QueryException( "persistent class not found: " + type );
		return persister;
	
org.hibernate.persister.entity.QueryablegetEntityPersisterUsingImports(java.lang.String className)

		final String importedClassName = getFactory().getImportedClassName( className );
		if ( importedClassName == null ) {
			return null;
		}
		try {
			return ( Queryable ) getFactory().getEntityPersister( importedClassName );
		}
		catch ( MappingException me ) {
			return null;
		}
	
protected org.hibernate.persister.entity.Loadable[]getEntityPersisters()
Persisters for the return values of a find() style query.

return
an array of EntityPersisters.

		return persisters;
	
public java.lang.ClassgetHolderClass()

		return holderClass;
	
protected org.hibernate.LockMode[]getLockModes(java.util.Map lockModes)

		// unfortunately this stuff can't be cached because
		// it is per-invocation, not constant for the
		// QueryTranslator instance
		HashMap nameLockModes = new HashMap();
		if ( lockModes != null ) {
			Iterator iter = lockModes.entrySet().iterator();
			while ( iter.hasNext() ) {
				Map.Entry me = ( Map.Entry ) iter.next();
				nameLockModes.put( getAliasName( ( String ) me.getKey() ),
						me.getValue() );
			}
		}
		LockMode[] lockModeArray = new LockMode[names.length];
		for ( int i = 0; i < names.length; i++ ) {
			LockMode lm = ( LockMode ) nameLockModes.get( names[i] );
			if ( lm == null ) lm = LockMode.NONE;
			lockModeArray[i] = lm;
		}
		return lockModeArray;
	
public int[]getNamedParameterLocs(java.lang.String name)

		Object o = namedParameters.get( name );
		if ( o == null ) {
			QueryException qe = new QueryException( ERROR_NAMED_PARAMETER_DOES_NOT_APPEAR + name );
			qe.setQueryString( queryString );
			throw qe;
		}
		if ( o instanceof Integer ) {
			return new int[]{ ( ( Integer ) o ).intValue() };
		}
		else {
			return ArrayHelper.toIntArray( ( ArrayList ) o );
		}
	
protected org.hibernate.type.EntityType[]getOwnerAssociationTypes()

		return ownerAssociationTypes;
	
protected int[]getOwners()

		return owners;
	
public org.hibernate.hql.ParameterTranslationsgetParameterTranslations()

		return new ParameterTranslations() {

			public boolean supportsOrdinalParameterMetadata() {
				// classic translator does not support collection of ordinal
				// param metadata
				return false;
			}

			public int getOrdinalParameterCount() {
				return 0; // not known!
			}

			public int getOrdinalParameterSqlLocation(int ordinalPosition) {
				return 0; // not known!
			}

			public Type getOrdinalParameterExpectedType(int ordinalPosition) {
				return null; // not known!
			}

			public Set getNamedParameterNames() {
				return namedParameters.keySet();
			}

			public int[] getNamedParameterSqlLocations(String name) {
				return getNamedParameterLocs( name );
			}

			public Type getNamedParameterExpectedType(String name) {
				return null; // not known!
			}
		};
	
java.lang.StringgetPathAlias(java.lang.String path)

		return ( String ) pathAliases.get( path );
	
org.hibernate.engine.JoinSequencegetPathJoin(java.lang.String path)

		return ( JoinSequence ) pathJoins.get( path );
	
org.hibernate.persister.entity.PropertyMappinggetPropertyMapping(java.lang.String name)

		PropertyMapping decorator = getDecoratedPropertyMapping( name );
		if ( decorator != null ) return decorator;

		String type = getType( name );
		if ( type == null ) {
			String role = getRole( name );
			if ( role == null ) {
				throw new QueryException( "alias not found: " + name );
			}
			return getCollectionPersister( role ); //.getElementPropertyMapping();
		}
		else {
			Queryable persister = getEntityPersister( type );
			if ( persister == null ) throw new QueryException( "persistent class not found: " + type );
			return persister;
		}
	
public java.lang.StringgetQueryIdentifier()

		return queryIdentifier;
	
public final java.util.SetgetQuerySpaces()

		return querySpaces;
	
public java.lang.StringgetQueryString()

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

		row = toResultRow( row );
		if ( hasScalars ) {
			String[][] scalarColumns = getColumnNames();
			int queryCols = returnTypes.length;
			if ( holderClass == null && queryCols == 1 ) {
				return returnTypes[0].nullSafeGet( rs, scalarColumns[0], session, null );
			}
			else {
				row = new Object[queryCols];
				for ( int i = 0; i < queryCols; i++ )
					row[i] = returnTypes[i].nullSafeGet( rs, scalarColumns[i], session, null );
				return row;
			}
		}
		else if ( holderClass == null ) {
			return row.length == 1 ? row[0] : row;
		}
		else {
			return row;
		}

	
protected java.util.ListgetResultList(java.util.List results, org.hibernate.transform.ResultTransformer resultTransformer)

		if ( holderClass != null ) {
			for ( int i = 0; i < results.size(); i++ ) {
				Object[] row = ( Object[] ) results.get( i );
				try {
					results.set( i, holderConstructor.newInstance( row ) );
				}
				catch ( Exception e ) {
					throw new QueryException( "could not instantiate: " + holderClass, e );
				}
			}
		}
		return results;
	
public java.lang.String[]getReturnAliases()

		// return aliases not supported in classic translator!
		return NO_RETURN_ALIASES;
	
public org.hibernate.type.Type[]getReturnTypes()
Types of the return values of an iterate() style query.

return
an array of Types.

		return actualReturnTypes;
	
private java.lang.StringgetRole(java.lang.String name)

		String role = ( String ) collections.get( name );
		if ( role == null && superQuery != null ) {
			role = superQuery.getRole( name );
		}
		return role;
	
public java.lang.StringgetSQLString()

		return sqlString;
	
protected java.lang.String[]getSuffixes()

		return suffixes;
	
private java.lang.StringgetType(java.lang.String name)

		String type = ( String ) typeMap.get( name );
		if ( type == null && superQuery != null ) {
			type = superQuery.getType( name );
		}
		return type;
	
protected booleanisCompiled()

		return compiled;
	
public booleanisManipulationStatement()

		// classic parser does not support bulk manipulation statements
		return false;
	
booleanisName(java.lang.String name)

		return aliasNames.containsKey( name ) ||
				typeMap.containsKey( name ) ||
				collections.containsKey( name ) || (
				superQuery != null && superQuery.isName( name )
				);
	
booleanisShallowQuery()
Is this query called by scroll() or iterate()?

return
true if it is, false if it is called by find() or list()

		return shallowQuery;
	
booleanisSubquery()

		return superQuery != null;
	
protected booleanisSubselectLoadingEnabled()

		return hasSubselectLoadableCollections();
	
public java.util.Iteratoriterate(org.hibernate.engine.QueryParameters queryParameters, org.hibernate.event.EventSource session)
Return the query results as an iterator


		boolean stats = session.getFactory().getStatistics().isStatisticsEnabled();
		long startTime = 0;
		if ( stats ) startTime = System.currentTimeMillis();

		try {

			PreparedStatement st = prepareQueryStatement( queryParameters, false, session );
			ResultSet rs = getResultSet( st, queryParameters.hasAutoDiscoverScalarTypes(), false, queryParameters.getRowSelection(), session );
			HolderInstantiator hi = HolderInstantiator.createClassicHolderInstantiator(holderConstructor, queryParameters.getResultTransformer());
			Iterator result = new IteratorImpl( rs, st, session, returnTypes, getColumnNames(), hi );

			if ( stats ) {
				session.getFactory().getStatisticsImplementor().queryExecuted(
						"HQL: " + queryString,
						0,
						System.currentTimeMillis() - startTime
					);
			}

			return result;

		}
		catch ( SQLException sqle ) {
			throw JDBCExceptionHelper.convert(
					getFactory().getSQLExceptionConverter(),
					sqle,
					"could not execute query using iterate",
					getSQLString()
				);
		}

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

		return list( session, queryParameters, getQuerySpaces(), actualReturnTypes );
	
private static voidlogQuery(java.lang.String hql, java.lang.String sql)

		if ( log.isDebugEnabled() ) {
			log.debug( "HQL: " + hql );
			log.debug( "SQL: " + sql );
		}
	
private voidmergeJoins(org.hibernate.sql.JoinFragment ojf)


		Iterator iter = joins.entrySet().iterator();
		while ( iter.hasNext() ) {
			Map.Entry me = ( Map.Entry ) iter.next();
			String name = ( String ) me.getKey();
			JoinSequence join = ( JoinSequence ) me.getValue();
			join.setSelector( new JoinSequence.Selector() {
				public boolean includeSubclasses(String alias) {
					boolean include = returnedTypes.contains( alias ) && !isShallowQuery();
					return include;
				}
			} );

			if ( typeMap.containsKey( name ) ) {
				ojf.addFragment( join.toJoinFragment( enabledFilters, true ) );
			}
			else if ( collections.containsKey( name ) ) {
				ojf.addFragment( join.toJoinFragment( enabledFilters, true ) );
			}
			else {
				//name from a super query (a bit inelegant that it shows up here)
			}

		}

	
private intnextCount()

		return ( superQuery == null ) ? nameCount++ : superQuery.nameCount++;
	
private voidrenderIdentifierSelect(org.hibernate.sql.QuerySelect sql)

		int size = returnedTypes.size();

		for ( int k = 0; k < size; k++ ) {
			String name = ( String ) returnedTypes.get( k );
			String suffix = size == 1 ? "" : Integer.toString( k ) + '_";
			sql.addSelectFragmentString( persisters[k].identifierSelectFragment( name, suffix ) );
		}

	
private voidrenderPropertiesSelect(org.hibernate.sql.QuerySelect sql)

		int size = returnedTypes.size();
		for ( int k = 0; k < size; k++ ) {
			String suffix = size == 1 ? "" : Integer.toString( k ) + '_";
			String name = ( String ) returnedTypes.get( k );
			sql.addSelectFragmentString( persisters[k].propertySelectFragment( name, suffix, false ) );
		}
	
private voidrenderSQL()


		final int rtsize;
		if ( returnedTypes.size() == 0 && scalarTypes.size() == 0 ) {
			//ie no select clause in HQL
			returnedTypes = fromTypes;
			rtsize = returnedTypes.size();
		}
		else {
			rtsize = returnedTypes.size();
			Iterator iter = entitiesToFetch.iterator();
			while ( iter.hasNext() ) {
				returnedTypes.add( iter.next() );
			}
		}
		int size = returnedTypes.size();
		persisters = new Queryable[size];
		names = new String[size];
		owners = new int[size];
		ownerAssociationTypes = new EntityType[size];
		suffixes = new String[size];
		includeInSelect = new boolean[size];
		for ( int i = 0; i < size; i++ ) {
			String name = ( String ) returnedTypes.get( i );
			//if ( !isName(name) ) throw new QueryException("unknown type: " + name);
			persisters[i] = getEntityPersisterForName( name );
			// TODO: cannot use generateSuffixes() - it handles the initial suffix differently.
			suffixes[i] = ( size == 1 ) ? "" : Integer.toString( i ) + '_";
			names[i] = name;
			includeInSelect[i] = !entitiesToFetch.contains( name );
			if ( includeInSelect[i] ) selectLength++;
			if ( name.equals( collectionOwnerName ) ) collectionOwnerColumn = i;
			String oneToOneOwner = ( String ) oneToOneOwnerNames.get( name );
			owners[i] = ( oneToOneOwner == null ) ? -1 : returnedTypes.indexOf( oneToOneOwner );
			ownerAssociationTypes[i] = (EntityType) uniqueKeyOwnerReferences.get( name );
		}

		if ( ArrayHelper.isAllNegative( owners ) ) owners = null;

		String scalarSelect = renderScalarSelect(); //Must be done here because of side-effect! yuck...

		int scalarSize = scalarTypes.size();
		hasScalars = scalarTypes.size() != rtsize;

		returnTypes = new Type[scalarSize];
		for ( int i = 0; i < scalarSize; i++ ) {
			returnTypes[i] = ( Type ) scalarTypes.get( i );
		}

		QuerySelect sql = new QuerySelect( getFactory().getDialect() );
		sql.setDistinct( distinct );

		if ( !shallowQuery ) {
			renderIdentifierSelect( sql );
			renderPropertiesSelect( sql );
		}

		if ( collectionPersister != null ) {
			sql.addSelectFragmentString( collectionPersister.selectFragment( fetchName, "__" ) );
		}

		if ( hasScalars || shallowQuery ) sql.addSelectFragmentString( scalarSelect );

		//TODO: for some dialects it would be appropriate to add the renderOrderByPropertiesSelect() to other select strings
		mergeJoins( sql.getJoinFragment() );

		sql.setWhereTokens( whereTokens.iterator() );

		sql.setGroupByTokens( groupByTokens.iterator() );
		sql.setHavingTokens( havingTokens.iterator() );
		sql.setOrderByTokens( orderByTokens.iterator() );

		if ( collectionPersister != null && collectionPersister.hasOrdering() ) {
			sql.addOrderBy( collectionPersister.getSQLOrderByString( fetchName ) );
		}

		scalarColumnNames = NameGenerator.generateColumnNames( returnTypes, getFactory() );

		// initialize the Set of queried identifier spaces (ie. tables)
		Iterator iter = collections.values().iterator();
		while ( iter.hasNext() ) {
			CollectionPersister p = getCollectionPersister( ( String ) iter.next() );
			addQuerySpaces( p.getCollectionSpaces() );
		}
		iter = typeMap.keySet().iterator();
		while ( iter.hasNext() ) {
			Queryable p = getEntityPersisterForName( ( String ) iter.next() );
			addQuerySpaces( p.getQuerySpaces() );
		}

		sqlString = sql.toQueryString();

		if ( holderClass != null ) holderConstructor = ReflectHelper.getConstructor( holderClass, returnTypes );

		if ( hasScalars ) {
			actualReturnTypes = returnTypes;
		}
		else {
			actualReturnTypes = new Type[selectLength];
			int j = 0;
			for ( int i = 0; i < persisters.length; i++ ) {
				if ( includeInSelect[i] ) {
					actualReturnTypes[j++] = TypeFactory.manyToOne( persisters[i].getEntityName(), shallowQuery );
				}
			}
		}

	
private java.lang.StringrenderScalarSelect()
WARNING: side-effecty


		boolean isSubselect = superQuery != null;

		StringBuffer buf = new StringBuffer( 20 );

		if ( scalarTypes.size() == 0 ) {
			//ie. no select clause
			int size = returnedTypes.size();
			for ( int k = 0; k < size; k++ ) {

				scalarTypes.add( TypeFactory.manyToOne( persisters[k].getEntityName(), shallowQuery ) );

				String[] idColumnNames = persisters[k].getIdentifierColumnNames();
				for ( int i = 0; i < idColumnNames.length; i++ ) {
					buf.append( returnedTypes.get( k ) ).append( '." ).append( idColumnNames[i] );
					if ( !isSubselect ) buf.append( " as " ).append( NameGenerator.scalarName( k, i ) );
					if ( i != idColumnNames.length - 1 || k != size - 1 ) buf.append( ", " );
				}

			}

		}
		else {
			//there _was_ a select clause
			Iterator iter = scalarSelectTokens.iterator();
			int c = 0;
			boolean nolast = false; //real hacky...
			int parenCount = 0; // used to count the nesting of parentheses
			while ( iter.hasNext() ) {
				Object next = iter.next();
				if ( next instanceof String ) {
					String token = ( String ) next;

					if ( "(".equals( token ) ) {
						parenCount++;
					}
					else if ( ")".equals( token ) ) {
						parenCount--;
					}

					String lc = token.toLowerCase();
					if ( lc.equals( ", " ) ) {
						if ( nolast ) {
							nolast = false;
						}
						else {
							if ( !isSubselect && parenCount == 0 ) {
								int x = c++;
								buf.append( " as " )
										.append( NameGenerator.scalarName( x, 0 ) );
							}
						}
					}
					buf.append( token );
					if ( lc.equals( "distinct" ) || lc.equals( "all" ) ) {
						buf.append( ' " );
					}
				}
				else {
					nolast = true;
					String[] tokens = ( String[] ) next;
					for ( int i = 0; i < tokens.length; i++ ) {
						buf.append( tokens[i] );
						if ( !isSubselect ) {
							buf.append( " as " )
									.append( NameGenerator.scalarName( c, i ) );
						}
						if ( i != tokens.length - 1 ) buf.append( ", " );
					}
					c++;
				}
			}
			if ( !isSubselect && !nolast ) {
				int x = c++;
				buf.append( " as " )
						.append( NameGenerator.scalarName( x, 0 ) );
			}

		}

		return buf.toString();
	
public org.hibernate.ScrollableResultsscroll(org.hibernate.engine.QueryParameters queryParameters, org.hibernate.engine.SessionImplementor session)

		HolderInstantiator hi = HolderInstantiator.createClassicHolderInstantiator(holderConstructor, queryParameters.getResultTransformer());
		return scroll( queryParameters, returnTypes, hi, session );
	
voidsetAliasName(java.lang.String alias, java.lang.String name)

		aliasNames.put( alias, name );
	
voidsetCollectionToFetch(java.lang.String role, java.lang.String name, java.lang.String ownerName, java.lang.String entityName)

		fetchName = name;
		collectionPersister = getCollectionPersister( role );
		collectionOwnerName = ownerName;
		if ( collectionPersister.getElementType().isEntityType() ) {
			addEntityToFetch( entityName );
		}
	
voidsetDistinct(boolean distinct)

		this.distinct = distinct;
	
voidsetHolderClass(java.lang.Class clazz)

		holderClass = clazz;
	
private java.lang.Object[]toResultRow(java.lang.Object[] row)

		if ( selectLength == row.length ) {
			return row;
		}
		else {
			Object[] result = new Object[selectLength];
			int j = 0;
			for ( int i = 0; i < row.length; i++ ) {
				if ( includeInSelect[i] ) result[j++] = row[i];
			}
			return result;
		}
	
public java.lang.StringtoString()

		return queryString;
	
java.lang.Stringunalias(java.lang.String path)

		String alias = StringHelper.root( path );
		String name = getAliasName( alias );
		if ( name != null ) {
			return name + path.substring( alias.length() );
		}
		else {
			return path;
		}
	
protected booleanupgradeLocks()

		return true;
	
public voidvalidateScrollability()

		// This is the legacy behaviour for HQL queries...
		if ( getCollectionPersisters() != null ) {
			throw new HibernateException( "Cannot scroll queries which initialize collections" );
		}