private Queryable determineAppropriateOwnerPersister(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); }
public CustomLoader(CustomQuery customQuery, 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; List includeInResultRowList = new ArrayList(); 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( StringHelper.unquote(scalarRtn.getColumnAlias(), factory.getDialect()), scalarRtn.getType())); includeInResultRowList.add(true); hasScalars = true; } else if (ConstructorReturn.class.isInstance(rtn)) { final ConstructorReturn constructorReturn = (ConstructorReturn) rtn; resultTypes.add(null); // this bit makes me nervous includeInResultRowList.add(true); hasScalars = true; ScalarResultColumnProcessor[] scalarProcessors = new ScalarResultColumnProcessor[constructorReturn.getScalars().length]; int i = 0; for (ScalarReturn scalarReturn : constructorReturn.getScalars()) { scalarProcessors[i++] = new ScalarResultColumnProcessor( StringHelper.unquote(scalarReturn.getColumnAlias(), factory.getDialect()), scalarReturn.getType()); } resultColumnProcessors.add( new ConstructorResultColumnProcessor( constructorReturn.getTargetClass(), scalarProcessors)); } 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(-1); resultTypes.add(persister.getType()); specifiedAliases.add(rootRtn.getAlias()); entityAliases.add(rootRtn.getEntityAliases()); ArrayHelper.addAll(querySpaces, persister.getQuerySpaces()); includeInResultRowList.add(true); } 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(-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(-1); entityAliases.add(collRtn.getElementEntityAliases()); ArrayHelper.addAll(querySpaces, elementPersister.getQuerySpaces()); } includeInResultRowList.add(true); } else if (rtn instanceof EntityFetchReturn) { EntityFetchReturn fetchRtn = (EntityFetchReturn) rtn; NonScalarReturn ownerDescriptor = fetchRtn.getOwner(); int ownerIndex = nonScalarReturnList.indexOf(ownerDescriptor); entityOwners.add(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()); includeInResultRowList.add(false); } else if (rtn instanceof CollectionFetchReturn) { CollectionFetchReturn fetchRtn = (CollectionFetchReturn) rtn; NonScalarReturn ownerDescriptor = fetchRtn.getOwner(); int ownerIndex = nonScalarReturnList.indexOf(ownerDescriptor); collectionOwners.add(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(ownerIndex); entityAliases.add(fetchRtn.getElementEntityAliases()); ArrayHelper.addAll(querySpaces, elementPersister.getQuerySpaces()); } includeInResultRowList.add(false); } 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()])); this.includeInResultRow = ArrayHelper.toBooleanArray(includeInResultRowList); }