HHH-6491 Binding @SqlResultSetMapping

This commit is contained in:
Strong Liu 2012-07-03 14:03:14 +08:00
parent 10a6425770
commit 1a3c584991
22 changed files with 413 additions and 571 deletions

View File

@ -110,9 +110,7 @@ public void doSecondPass(Map persistentClasses) throws MappingException {
List<String> followers = getFollowers( parentPropIter, reducedName, name );
int index = propertyNames.size();
int followersSize = followers.size();
for (int loop = 0; loop < followersSize; loop++) {
String follower = followers.get( loop );
for (final String follower :followers) {
int currentIndex = getIndexOfFirstMatchingProperty( propertyNames, follower );
index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
}
@ -254,10 +252,10 @@ else if ( value instanceof ToOne ) {
return parentPropIter;
}
private static int getIndexOfFirstMatchingProperty(List propertyNames, String follower) {
private static int getIndexOfFirstMatchingProperty(List<String> propertyNames, String follower) {
int propertySize = propertyNames.size();
for (int propIndex = 0; propIndex < propertySize; propIndex++) {
if ( ( (String) propertyNames.get( propIndex ) ).startsWith( follower ) ) {
if ( ( propertyNames.get( propIndex ) ).startsWith( follower ) ) {
return propIndex;
}
}

View File

@ -115,4 +115,9 @@ private int determineHashCode() {
result = 31 * result + ( ownerProperty != null ? ownerProperty.hashCode() : 0 );
return result;
}
@Override
public Nature getNature() {
return Nature.COLLECTION;
}
}

View File

@ -110,4 +110,9 @@ private int determineHashCode() {
result = 31 * result + ( ownerProperty != null ? ownerProperty.hashCode() : 0 );
return result;
}
@Override
public Nature getNature() {
return Nature.JOIN;
}
}

View File

@ -33,4 +33,9 @@
* @author Steve Ebersole
*/
public interface NativeSQLQueryReturn {
public static enum Nature{
SCALAR, ROOT, COLLECTION, JOIN;
}
public Nature getNature();
}

View File

@ -101,4 +101,9 @@ private int determineHashCode() {
result = 31 * result + ( returnEntityName != null ? returnEntityName.hashCode() : 0 );
return result;
}
@Override
public Nature getNature() {
return Nature.ROOT;
}
}

View File

@ -79,4 +79,9 @@ private int determineHashCode() {
result = 31 * result + ( columnAlias != null ? columnAlias.hashCode() : 0 );
return result;
}
@Override
public Nature getNature() {
return Nature.SCALAR;
}
}

View File

@ -65,12 +65,12 @@ else if ( returnLists ) {
}
}
static public HolderInstantiator createClassicHolderInstantiator(Constructor constructor,
public static HolderInstantiator createClassicHolderInstantiator(Constructor constructor,
ResultTransformer transformer) {
return new HolderInstantiator( resolveClassicResultTransformer( constructor, transformer ), null );
}
static public ResultTransformer resolveClassicResultTransformer(
public static ResultTransformer resolveClassicResultTransformer(
Constructor constructor,
ResultTransformer transformer) {
return constructor != null ? new AliasToBeanConstructorResultTransformer( constructor ) : transformer;
@ -89,11 +89,7 @@ public boolean isRequired() {
}
public Object instantiate(Object[] row) {
if(transformer==null) {
return row;
} else {
return transformer.transformTuple(row, queryReturnAliases);
}
return transformer == null ? row : transformer.transformTuple(row, queryReturnAliases);
}
public String[] getQueryReturnAliases() {

View File

@ -498,7 +498,7 @@ public void sessionFactoryClosed(SessionFactory factory) {
//Named Queries:
namedQueries = new HashMap<String, NamedQueryDefinition>( cfg.getNamedQueries() );
namedSqlQueries = new HashMap<String, NamedSQLQueryDefinition>( cfg.getNamedSQLQueries() );
sqlResultSetMappings = new HashMap<String, ResultSetMappingDefinition>( cfg.getSqlResultSetMappings() );
sqlResultSetMappings = Collections.unmodifiableMap( new HashMap<String, ResultSetMappingDefinition>( cfg.getSqlResultSetMappings() ) );
imports = new HashMap<String,String>( cfg.getImports() );
// after *all* persisters and named queries are registered
@ -862,8 +862,7 @@ public void sessionFactoryClosed(SessionFactory factory) {
for ( NamedSQLQueryDefinition namedNativeQueryDefinition: metadata.getNamedNativeQueryDefinitions() ) {
namedSqlQueries.put( namedNativeQueryDefinition.getName(), namedNativeQueryDefinition );
}
sqlResultSetMappings = new HashMap<String, ResultSetMappingDefinition>();
sqlResultSetMappings.putAll( metadata.getResultSetMappingDefinitions() );
sqlResultSetMappings = Collections.unmodifiableMap( new HashMap<String, ResultSetMappingDefinition>( metadata.getResultSetMappingDefinitions() ) );
imports = new HashMap<String,String>();
for ( Map.Entry<String,String> importEntry : metadata.getImports() ) {
imports.put( importEntry.getKey(), importEntry.getValue() );

View File

@ -37,7 +37,7 @@
public class ColumnEntityAliases extends DefaultEntityAliases {
public ColumnEntityAliases(
Map returnProperties,
Map<String, String[]> returnProperties,
Loadable persister,
String suffix) {
super( returnProperties, persister, suffix );

View File

@ -28,6 +28,7 @@
import java.util.Map;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.persister.entity.Loadable;
/**
@ -45,7 +46,7 @@ public class DefaultEntityAliases implements EntityAliases {
private final String suffixedDiscriminatorColumn;
private final String suffix;
private final String rowIdAlias;
private final Map userProvidedAliases;
private final Map<String, String[]> userProvidedAliases;
/**
* Calculate and cache select-clause aliases
@ -55,17 +56,17 @@ public class DefaultEntityAliases implements EntityAliases {
* @param suffix The calculated suffix.
*/
public DefaultEntityAliases(
Map userProvidedAliases,
Map<String, String[]> userProvidedAliases,
Loadable persister,
String suffix) {
this.suffix = suffix;
this.userProvidedAliases = userProvidedAliases;
suffixedKeyColumns = determineKeyAlias( persister, suffix );
suffixedPropertyColumns = determinePropertyAliases( persister );
suffixedDiscriminatorColumn = determineDiscriminatorAlias( persister, suffix );
suffixedVersionColumn = determineVersionAlias( persister );
rowIdAlias = Loadable.ROWID_ALIAS + suffix; // TODO: not visible to the user!
this.suffixedKeyColumns = determineKeyAlias( persister, suffix );
this.suffixedPropertyColumns = determinePropertyAliases( persister );
this.suffixedDiscriminatorColumn = determineDiscriminatorAlias( persister, suffix );
this.suffixedVersionColumn = determineVersionAlias( persister );
this.rowIdAlias = Loadable.ROWID_ALIAS + suffix; // TODO: not visible to the user!
}
public DefaultEntityAliases(Loadable persister, String suffix) {
@ -117,23 +118,13 @@ protected String[] getPropertyAliases(Loadable persister, int j) {
}
private String[] getUserProvidedAliases(String propertyPath, String[] defaultAliases) {
String[] result = (String[]) userProvidedAliases.get(propertyPath);
if (result==null) {
return defaultAliases;
}
else {
return result;
}
String[] result = userProvidedAliases.get(propertyPath);
return CollectionHelper.isEmpty( result ) ? defaultAliases : result;
}
private String getUserProvidedAlias(String propertyPath, String defaultAlias) {
String[] columns = (String[]) userProvidedAliases.get(propertyPath);
if (columns==null) {
return defaultAlias;
}
else {
return columns[0];
}
String[] columns = userProvidedAliases.get(propertyPath);
return CollectionHelper.isEmpty( columns ) ? defaultAlias : columns[0];
}
/**
@ -189,7 +180,7 @@ public String getRowIdAlias() {
}
private static void intern(String[] strings) {
for (int i=0; i<strings.length; i++ ) {
for ( int i = 0; i < strings.length; i++ ) {
strings[i] = strings[i].intern();
}
}

View File

@ -22,7 +22,7 @@
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.loader.custom;
package org.hibernate.loader.custom;
import org.hibernate.LockMode;
import org.hibernate.loader.CollectionAliases;
import org.hibernate.loader.EntityAliases;
@ -55,4 +55,9 @@ public CollectionAliases getCollectionAliases() {
public EntityAliases getElementEntityAliases() {
return elementEntityAliases;
}
@Override
public Nature getNature() {
return Nature.COLLECTION_FETCH;
}
}

View File

@ -22,7 +22,7 @@
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.loader.custom;
package org.hibernate.loader.custom;
import org.hibernate.LockMode;
import org.hibernate.loader.CollectionAliases;
import org.hibernate.loader.EntityAliases;
@ -80,4 +80,9 @@ public CollectionAliases getCollectionAliases() {
public EntityAliases getElementEntityAliases() {
return elementEntityAliases;
}
@Override
public Nature getNature() {
return Nature.COLLECTION;
}
}

View File

@ -28,7 +28,6 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -82,9 +81,6 @@ public class CustomLoader extends Loader {
private final LockMode[] lockModes;
private boolean[] includeInResultRow;
// private final String[] sqlAliases;
// private final String[] sqlAliasSuffixes;
private final ResultRowProcessor rowProcessor;
// this is only needed (afaict) for processing results from the query cache;
@ -101,15 +97,15 @@ public CustomLoader(CustomQuery customQuery, SessionFactoryImplementor factory)
this.querySpaces.addAll( customQuery.getQuerySpaces() );
this.namedParameterBindPoints = customQuery.getNamedParameterBindPoints();
List entityPersisters = new ArrayList();
List entityOwners = new ArrayList();
List entityAliases = new ArrayList();
List<Queryable> entityPersisters = new ArrayList<Queryable>();
List<Integer> entityOwners = new ArrayList<Integer>();
List<EntityAliases> entityAliases = new ArrayList<EntityAliases>();
List collectionPersisters = new ArrayList();
List<QueryableCollection> collectionPersisters = new ArrayList<QueryableCollection>();
List collectionOwners = new ArrayList();
List collectionAliases = new ArrayList();
List<CollectionAliases> collectionAliases = new ArrayList<CollectionAliases>();
List lockModes = new ArrayList();
List<LockMode> lockModes = new ArrayList<LockMode>();
List resultColumnProcessors = new ArrayList();
List nonScalarReturnList = new ArrayList();
List resultTypes = new ArrayList();
@ -118,131 +114,118 @@ public CustomLoader(CustomQuery customQuery, SessionFactoryImplementor factory)
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 ( 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 );
for ( Return rtn : customQuery.getCustomQueryReturns() ) {
switch ( rtn.getNature() ) {
case SCALAR:
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;
break;
case ROOT:
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 );
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 );
resultTypes.add( persister.getType() );
specifiedAliases.add( rootRtn.getAlias() );
entityAliases.add( rootRtn.getEntityAliases() );
ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );
includeInResultRowList.add( true );
break;
case COLLECTION:
CollectionReturn collRtn = (CollectionReturn) rtn;
String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty();
QueryableCollection collectionPersister = (QueryableCollection) factory.getCollectionPersister( role );
collectionPersisters.add( collectionPersister );
lockModes.add( collRtn.getLockMode() );
resultColumnProcessors.add( new NonScalarResultColumnProcessor( returnableCounter++ ) );
nonScalarReturnList.add( rtn );
collectionOwners.add( -1 );
resultTypes.add( collectionPersister.getType() );
specifiedAliases.add( collRtn.getAlias() );
collectionAliases.add( collRtn.getCollectionAliases() );
// determine if the collection elements are entities...
Type elementType = collectionPersister.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 );
break;
case COLLECTION_FETCH:
CollectionFetchReturn collectionFetchReturn = (CollectionFetchReturn) rtn;
NonScalarReturn ownerDescriptor = collectionFetchReturn.getOwner();
int ownerIndex = nonScalarReturnList.indexOf( ownerDescriptor );
collectionOwners.add( ownerIndex );
lockModes.add( collectionFetchReturn.getLockMode() );
Queryable ownerPersister = determineAppropriateOwnerPersister( ownerDescriptor );
role = ownerPersister.getEntityName() + '.' + collectionFetchReturn.getOwnerProperty();
collectionPersister = (QueryableCollection) factory.getCollectionPersister( role );
collectionPersisters.add( collectionPersister );
nonScalarReturnList.add( rtn );
specifiedAliases.add( collectionFetchReturn.getAlias() );
collectionAliases.add( collectionFetchReturn.getCollectionAliases() );
// determine if the collection elements are entities...
elementType = collectionPersister.getElementType();
if ( elementType.isEntityType() ) {
Queryable elementPersister = (Queryable) ( (EntityType) elementType ).getAssociatedJoinable(
factory
);
entityPersisters.add( elementPersister );
entityOwners.add( ownerIndex );
entityAliases.add( collectionFetchReturn.getElementEntityAliases() );
ArrayHelper.addAll( querySpaces, elementPersister.getQuerySpaces() );
}
includeInResultRowList.add( false );
break;
case ENTITY_FETCH:
EntityFetchReturn fetchRtn = (EntityFetchReturn) rtn;
ownerDescriptor = fetchRtn.getOwner();
ownerIndex = nonScalarReturnList.indexOf( ownerDescriptor );
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() );
lockModes.add( fetchRtn.getLockMode() );
ownerPersister = determineAppropriateOwnerPersister( ownerDescriptor );
EntityType fetchedType = (EntityType) ownerPersister.getPropertyType( fetchRtn.getOwnerProperty() );
String entityName = fetchedType.getAssociatedEntityName( getFactory() );
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 );
break;
default:
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.entityPersisters = entityPersisters.toArray( new Queryable[ entityPersisters.size() ]);
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.entityAliases = entityAliases.toArray( new EntityAliases[ entityAliases.size() ] );
this.collectionPersisters = new QueryableCollection[ collectionPersisters.size() ];
for ( int i = 0; i < collectionPersisters.size(); i++ ) {
this.collectionPersisters[i] = ( QueryableCollection ) collectionPersisters.get( i );
}
this.collectionPersisters = collectionPersisters.toArray( new QueryableCollection[ collectionPersisters.size() ] );
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.collectionAliases = collectionAliases.toArray( new CollectionAliases[ collectionAliases.size() ] );
this.lockModes = lockModes.toArray( new LockMode[ lockModes.size() ] );
this.resultTypes = ArrayHelper.toTypeArray( resultTypes );
this.transformerAliases = ArrayHelper.toStringArray( specifiedAliases );
@ -256,35 +239,35 @@ else if ( rtn instanceof CollectionFetchReturn ) {
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() );
switch ( ownerDescriptor.getNature() ) {
case ROOT:
entityName = ( (RootReturn) ownerDescriptor ).getEntityName();
break;
case COLLECTION:
CollectionReturn collRtn = (CollectionReturn) ownerDescriptor;
String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty();
CollectionPersister collectionPersister = getFactory().getCollectionPersister( role );
EntityType entityOwnerType = (EntityType) collectionPersister.getElementType();
entityName = entityOwnerType.getAssociatedEntityName( getFactory() );
break;
case ENTITY_FETCH:
case COLLECTION_FETCH:
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() );
}
}
break;
default:
throw new HibernateException( "Could not determine fetch owner : " + ownerDescriptor );
}
if ( entityName == null ) {
throw new HibernateException( "Could not determine fetch owner : " + ownerDescriptor );
}
return ( Queryable ) getFactory().getEntityPersister( entityName );
}
@ -343,12 +326,10 @@ public ScrollableResults scroll(
}
static private HolderInstantiator getHolderInstantiator(ResultTransformer resultTransformer, String[] queryReturnAliases) {
if ( resultTransformer == null ) {
return HolderInstantiator.NOOP_INSTANTIATOR;
}
else {
return new HolderInstantiator(resultTransformer, queryReturnAliases);
}
return resultTransformer == null ? HolderInstantiator.NOOP_INSTANTIATOR : new HolderInstantiator(
resultTransformer,
queryReturnAliases
);
}
@Override
@ -390,7 +371,7 @@ protected List getResultList(List results, ResultTransformer resultTransformer)
getReturnAliasesForTransformer()
);
if ( holderInstantiator.isRequired() ) {
for ( int i = 0; i < results.size(); i++ ) {
for ( int i = 0, size = results.size(); i < size; i++ ) {
Object[] row = ( Object[] ) results.get( i );
Object result = holderInstantiator.instantiate(row);
results.set( i, result );
@ -426,12 +407,7 @@ public int[] getNamedParameterLocs(String name) throws QueryException {
sql
);
}
if ( loc instanceof Integer ) {
return new int[] { ( ( Integer ) loc ).intValue() };
}
else {
return ArrayHelper.toIntArray( ( List ) loc );
}
return Integer.class.isInstance( loc ) ? new int[] {Integer.class.cast( loc )} : ArrayHelper.toIntArray( (List)loc );
}
@ -622,7 +598,7 @@ public Metadata(SessionFactoryImplementor factory, ResultSet resultSet) throws H
}
}
public int getColumnCount() throws HibernateException {
public int getColumnCount(){
try {
return resultSetMetaData.getColumnCount();
}
@ -631,7 +607,7 @@ public int getColumnCount() throws HibernateException {
}
}
public int resolveColumnPosition(String columnName) throws HibernateException {
public int resolveColumnPosition(String columnName){
try {
return resultSet.findColumn( columnName );
}
@ -640,7 +616,7 @@ public int resolveColumnPosition(String columnName) throws HibernateException {
}
}
public String getColumnName(int position) throws HibernateException {
public String getColumnName(int position) {
try {
return factory.getDialect().getColumnAliasExtractor().extractColumnAlias( resultSetMetaData, position );
}

View File

@ -73,5 +73,5 @@ public interface CustomQuery {
*
* @return List of return descriptors.
*/
public List getCustomQueryReturns();
public List<Return> getCustomQueryReturns();
}

View File

@ -22,7 +22,7 @@
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.loader.custom;
package org.hibernate.loader.custom;
import org.hibernate.LockMode;
import org.hibernate.loader.EntityAliases;
@ -47,4 +47,9 @@ public EntityFetchReturn(
public EntityAliases getEntityAliases() {
return entityAliases;
}
@Override
public Nature getNature() {
return Nature.ENTITY_FETCH;
}
}

View File

@ -22,7 +22,7 @@
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.loader.custom;
package org.hibernate.loader.custom;
/**
@ -31,4 +31,8 @@
* @author Steve Ebersole
*/
public interface Return {
public static enum Nature{
SCALAR, ROOT, COLLECTION, ENTITY_FETCH, COLLECTION_FETCH;
}
public Nature getNature();
}

View File

@ -22,7 +22,7 @@
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.loader.custom;
package org.hibernate.loader.custom;
import org.hibernate.LockMode;
import org.hibernate.loader.EntityAliases;
@ -55,4 +55,9 @@ public String getEntityName() {
public EntityAliases getEntityAliases() {
return entityAliases;
}
@Override
public Nature getNature() {
return Nature.ROOT;
}
}

View File

@ -22,7 +22,7 @@
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.loader.custom;
package org.hibernate.loader.custom;
import org.hibernate.type.Type;
/**
@ -46,4 +46,9 @@ public Type getType() {
public String getColumnAlias() {
return columnAlias;
}
@Override
public Nature getNature() {
return Nature.SCALAR;
}
}

View File

@ -38,6 +38,7 @@
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.loader.custom.CustomQuery;
import org.hibernate.loader.custom.Return;
import org.hibernate.persister.collection.SQLLoadableCollection;
import org.hibernate.persister.entity.SQLLoadable;
@ -57,22 +58,22 @@ public class SQLCustomQuery implements CustomQuery {
private final String sql;
private final Set querySpaces = new HashSet();
private final Map namedParameterBindPoints = new HashMap();
private final List customQueryReturns = new ArrayList();
private final List<Return> customQueryReturns = new ArrayList<Return>();
@Override
public String getSQL() {
return sql;
}
@Override
public Set getQuerySpaces() {
return querySpaces;
}
@Override
public Map getNamedParameterBindPoints() {
return namedParameterBindPoints;
}
public List getCustomQueryReturns() {
@Override
public List<Return> getCustomQueryReturns() {
return customQueryReturns;
}
@ -86,133 +87,14 @@ public SQLCustomQuery(
SQLQueryReturnProcessor processor = new SQLQueryReturnProcessor(queryReturns, factory);
SQLQueryReturnProcessor.ResultAliasContext aliasContext = processor.process();
// Map[] propertyResultMaps = (Map[]) processor.getPropertyResults().toArray( new Map[0] );
// Map[] collectionResultMaps = (Map[]) processor.getCollectionPropertyResults().toArray( new Map[0] );
//
// List collectionSuffixes = new ArrayList();
// List collectionOwnerAliases = processor.getCollectionOwnerAliases();
// List collectionPersisters = processor.getCollectionPersisters();
// int size = collectionPersisters.size();
// if (size!=0) {
// collectionOwners = new int[size];
// collectionRoles = new String[size];
// //collectionDescriptors = new CollectionAliases[size];
// for ( int i=0; i<size; i++ ) {
// CollectionPersister collectionPersister = (CollectionPersister) collectionPersisters.get(i);
// collectionRoles[i] = ( collectionPersister ).getRole();
// collectionOwners[i] = processor.getAliases().indexOf( collectionOwnerAliases.get(i) );
// String suffix = i + "__";
// collectionSuffixes.add(suffix);
// //collectionDescriptors[i] = new GeneratedCollectionAliases( collectionResultMaps[i], collectionPersister, suffix );
// }
// }
// else {
// collectionRoles = null;
// //collectionDescriptors = null;
// collectionOwners = null;
// }
//
// String[] aliases = ArrayHelper.toStringArray( processor.getAliases() );
// String[] collAliases = ArrayHelper.toStringArray( processor.getCollectionAliases() );
// String[] collSuffixes = ArrayHelper.toStringArray(collectionSuffixes);
//
// SQLLoadable[] entityPersisters = (SQLLoadable[]) processor.getPersisters().toArray( new SQLLoadable[0] );
// SQLLoadableCollection[] collPersisters = (SQLLoadableCollection[]) collectionPersisters.toArray( new SQLLoadableCollection[0] );
// lockModes = (LockMode[]) processor.getLockModes().toArray( new LockMode[0] );
//
// scalarColumnAliases = ArrayHelper.toStringArray( processor.getScalarColumnAliases() );
// scalarTypes = ArrayHelper.toTypeArray( processor.getScalarTypes() );
//
// // need to match the "sequence" of what we return. scalar first, entity last.
// returnAliases = ArrayHelper.join(scalarColumnAliases, aliases);
//
// String[] suffixes = BasicLoader.generateSuffixes(entityPersisters.length);
SQLQueryParser parser = new SQLQueryParser( sqlQuery, new ParserContext( aliasContext ), factory );
this.sql = parser.process();
this.namedParameterBindPoints.putAll( parser.getNamedParameters() );
// SQLQueryParser parser = new SQLQueryParser(
// sqlQuery,
// processor.getAlias2Persister(),
// processor.getAlias2Return(),
// aliases,
// collAliases,
// collPersisters,
// suffixes,
// collSuffixes
// );
//
// sql = parser.process();
//
// namedParameterBindPoints = parser.getNamedParameters();
customQueryReturns.addAll( processor.generateCustomReturns( parser.queryHasAliases() ) );
// // Populate entityNames, entityDescrptors and querySpaces
// entityNames = new String[entityPersisters.length];
// entityDescriptors = new EntityAliases[entityPersisters.length];
// for (int i = 0; i < entityPersisters.length; i++) {
// SQLLoadable persister = entityPersisters[i];
// //alias2Persister.put( aliases[i], persister );
// //TODO: Does not consider any other tables referenced in the query
// ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );
// entityNames[i] = persister.getEntityName();
// if ( parser.queryHasAliases() ) {
// entityDescriptors[i] = new DefaultEntityAliases(
// propertyResultMaps[i],
// entityPersisters[i],
// suffixes[i]
// );
// }
// else {
// entityDescriptors[i] = new ColumnEntityAliases(
// propertyResultMaps[i],
// entityPersisters[i],
// suffixes[i]
// );
// }
// }
this.customQueryReturns.addAll( processor.generateCustomReturns( parser.queryHasAliases() ) );
if ( additionalQuerySpaces != null ) {
querySpaces.addAll( additionalQuerySpaces );
}
// if (size!=0) {
// collectionDescriptors = new CollectionAliases[size];
// for ( int i=0; i<size; i++ ) {
// CollectionPersister collectionPersister = (CollectionPersister) collectionPersisters.get(i);
// String suffix = i + "__";
// if( parser.queryHasAliases() ) {
// collectionDescriptors[i] = new GeneratedCollectionAliases( collectionResultMaps[i], collectionPersister, suffix );
// } else {
// collectionDescriptors[i] = new ColumnCollectionAliases( collectionResultMaps[i], (SQLLoadableCollection) collectionPersister );
// }
// }
// }
// else {
// collectionDescriptors = null;
// }
//
//
// // Resolve owners
// Map alias2OwnerAlias = processor.getAlias2OwnerAlias();
// int[] ownersArray = new int[entityPersisters.length];
// for ( int j=0; j < aliases.length; j++ ) {
// String ownerAlias = (String) alias2OwnerAlias.get( aliases[j] );
// if ( StringHelper.isNotEmpty(ownerAlias) ) {
// ownersArray[j] = processor.getAliases().indexOf( ownerAlias );
// }
// else {
// ownersArray[j] = -1;
// }
// }
// if ( ArrayHelper.isAllNegative(ownersArray) ) {
// ownersArray = null;
// }
// this.entityOwners = ownersArray;
}
@ -223,32 +105,32 @@ private static class ParserContext implements SQLQueryParser.ParserContext {
public ParserContext(SQLQueryReturnProcessor.ResultAliasContext aliasContext) {
this.aliasContext = aliasContext;
}
@Override
public boolean isEntityAlias(String alias) {
return getEntityPersisterByAlias( alias ) != null;
}
@Override
public SQLLoadable getEntityPersisterByAlias(String alias) {
return aliasContext.getEntityPersister( alias );
}
@Override
public String getEntitySuffixByAlias(String alias) {
return aliasContext.getEntitySuffix( alias );
}
@Override
public boolean isCollectionAlias(String alias) {
return getCollectionPersisterByAlias( alias ) != null;
}
@Override
public SQLLoadableCollection getCollectionPersisterByAlias(String alias) {
return aliasContext.getCollectionPersister( alias );
}
@Override
public String getCollectionSuffixByAlias(String alias) {
return aliasContext.getCollectionSuffix( alias );
}
public Map getPropertyResultsMapByAlias(String alias) {
@Override
public Map<String, String[]> getPropertyResultsMapByAlias(String alias) {
return aliasContext.getPropertyResultsMap( alias );
}
}

View File

@ -60,7 +60,7 @@ static interface ParserContext {
boolean isCollectionAlias(String aliasName);
SQLLoadableCollection getCollectionPersisterByAlias(String alias);
String getCollectionSuffixByAlias(String alias);
Map getPropertyResultsMapByAlias(String alias);
Map<String, String[]> getPropertyResultsMapByAlias(String alias);
}
public SQLQueryParser(String queryString, ParserContext context, SessionFactoryImplementor factory) {
@ -99,7 +99,7 @@ private String substituteBrackets(String sqlQuery) throws QueryException {
break;
}
// apend everything up until the next encountered open brace
// append everything up until the next encountered open brace
result.append( sqlQuery.substring( curr, left ) );
if ( ( right = sqlQuery.indexOf( '}', left + 1 ) ) < 0 ) {
@ -112,32 +112,16 @@ private String substituteBrackets(String sqlQuery) throws QueryException {
if ( isPlaceholder ) {
// Domain replacement
if ( DOMAIN_PLACEHOLDER.equals( aliasPath ) ) {
final String catalogName = factory.getSettings().getDefaultCatalogName();
if ( catalogName != null ) {
result.append( catalogName );
result.append( "." );
}
final String schemaName = factory.getSettings().getDefaultSchemaName();
if ( schemaName != null ) {
result.append( schemaName );
result.append( "." );
}
appendCatalog( result );
appendSchema( result );
}
// Schema replacement
else if ( SCHEMA_PLACEHOLDER.equals( aliasPath ) ) {
final String schemaName = factory.getSettings().getDefaultSchemaName();
if ( schemaName != null ) {
result.append(schemaName);
result.append(".");
}
appendSchema(result);
}
// Catalog replacement
else if ( CATALOG_PLACEHOLDER.equals( aliasPath ) ) {
final String catalogName = factory.getSettings().getDefaultCatalogName();
if ( catalogName != null ) {
result.append( catalogName );
result.append( "." );
}
appendCatalog( result );
}
else {
throw new QueryException( "Unknown placeholder ", aliasPath );
@ -181,13 +165,29 @@ else if ( context.isEntityAlias( aliasName ) ) {
// Possibly handle :something parameters for the query ?
return result.toString();
}
}
private void appendSchema(StringBuilder result) {
final String schemaName = factory.getSettings().getDefaultSchemaName();
if ( schemaName != null ) {
result.append( schemaName );
result.append( "." );
}
}
private void appendCatalog(StringBuilder result) {
final String catalogName = factory.getSettings().getDefaultCatalogName();
if ( catalogName != null ) {
result.append( catalogName );
result.append( "." );
}
}
private String resolveCollectionProperties(
String aliasName,
String propertyName) {
Map fieldResults = context.getPropertyResultsMapByAlias( aliasName );
Map<String, String[]> fieldResults = context.getPropertyResultsMapByAlias( aliasName );
SQLLoadableCollection collectionPersister = context.getCollectionPersisterByAlias( aliasName );
String collectionSuffix = context.getCollectionSuffixByAlias( aliasName );
@ -206,10 +206,8 @@ else if ( "element.*".equals( propertyName ) ) {
return resolveProperties( aliasName, "*" );
}
else {
String[] columnAliases;
// Let return-propertys override whatever the persister has for aliases.
columnAliases = ( String[] ) fieldResults.get(propertyName);
String[] columnAliases = fieldResults.get(propertyName);
if ( columnAliases==null ) {
columnAliases = collectionPersister.getCollectionPropertyColumnAliases( propertyName, collectionSuffix );
}
@ -236,7 +234,7 @@ else if ( "element.*".equals( propertyName ) ) {
private String resolveProperties(
String aliasName,
String propertyName) {
Map fieldResults = context.getPropertyResultsMapByAlias( aliasName );
Map<String, String[]> fieldResults = context.getPropertyResultsMapByAlias( aliasName );
SQLLoadable persister = context.getEntityPersisterByAlias( aliasName );
String suffix = context.getEntitySuffixByAlias( aliasName );
@ -248,11 +246,8 @@ private String resolveProperties(
return persister.selectFragment( aliasName, suffix ) ;
}
else {
String[] columnAliases;
// Let return-propertys override whatever the persister has for aliases.
columnAliases = (String[]) fieldResults.get( propertyName );
String[] columnAliases = fieldResults.get( propertyName );
if ( columnAliases == null ) {
columnAliases = persister.getSubclassPropertyColumnAliases( propertyName, suffix );
}
@ -266,7 +261,8 @@ private String resolveProperties(
if ( columnAliases.length != 1 ) {
// TODO: better error message since we actually support composites if names are explicitly listed.
throw new QueryException(
"SQL queries only support properties mapped to a single column - property [" + propertyName + "] is mapped to " + columnAliases.length + " columns.",
"SQL queries only support properties mapped to a single column - property [" + propertyName
+ "] is mapped to " + columnAliases.length + " columns.",
originalQueryString
);
}
@ -321,7 +317,7 @@ public void other(char character) {
}
private void addNamedParameter(String name) {
Integer loc = parameterCount++;
int loc = parameterCount++;
Object o = namedParameterBindPoints.get( name );
if ( o == null ) {
namedParameterBindPoints.put( name, loc );

View File

@ -25,7 +25,6 @@
package org.hibernate.loader.custom.sql;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -41,6 +40,7 @@
import org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.loader.BasicLoader;
import org.hibernate.loader.CollectionAliases;
import org.hibernate.loader.ColumnEntityAliases;
@ -78,31 +78,18 @@ public class SQLQueryReturnProcessor {
SQLQueryReturnProcessor.class.getName());
private NativeSQLQueryReturn[] queryReturns;
private final Map<String, NativeSQLQueryReturn> alias2Return = new HashMap<String, NativeSQLQueryReturn>();
private final Map<String, String> alias2OwnerAlias = new HashMap<String, String>();
// private final List persisters = new ArrayList();
private final Map<String, SQLLoadable> alias2Persister = new HashMap<String, SQLLoadable>();
private final Map<String, String> alias2Suffix = new HashMap<String, String>();
private final Map alias2Return = new HashMap();
private final Map alias2OwnerAlias = new HashMap();
private final Map alias2Persister = new HashMap();
private final Map alias2Suffix = new HashMap();
private final Map alias2CollectionPersister = new HashMap();
private final Map alias2CollectionSuffix = new HashMap();
private final Map entityPropertyResultMaps = new HashMap();
private final Map collectionPropertyResultMaps = new HashMap();
// private final List scalarTypes = new ArrayList();
// private final List scalarColumnAliases = new ArrayList();
private final Map<String, SQLLoadableCollection> alias2CollectionPersister = new HashMap<String, SQLLoadableCollection>();
private final Map<String, String> alias2CollectionSuffix = new HashMap<String, String>();
private final Map<String, Map<String, String[]>> entityPropertyResultMaps = new HashMap<String, Map<String, String[]>>();
private final Map<String, Map<String, String[]>> collectionPropertyResultMaps = new HashMap<String, Map<String, String[]>>();
private final SessionFactoryImplementor factory;
// private List collectionOwnerAliases = new ArrayList();
// private List collectionAliases = new ArrayList();
// private List collectionPersisters = new ArrayList();
// private List collectionResults = new ArrayList();
private int entitySuffixSeed = 0;
private int collectionSuffixSeed = 0;
@ -114,53 +101,48 @@ public SQLQueryReturnProcessor(NativeSQLQueryReturn[] queryReturns, SessionFacto
/*package*/ class ResultAliasContext {
public SQLLoadable getEntityPersister(String alias) {
return ( SQLLoadable ) alias2Persister.get( alias );
return alias2Persister.get( alias );
}
public SQLLoadableCollection getCollectionPersister(String alias) {
return ( SQLLoadableCollection ) alias2CollectionPersister.get( alias );
return alias2CollectionPersister.get( alias );
}
public String getEntitySuffix(String alias) {
return ( String ) alias2Suffix.get( alias );
return alias2Suffix.get( alias );
}
public String getCollectionSuffix(String alias) {
return ( String ) alias2CollectionSuffix.get ( alias );
return alias2CollectionSuffix.get ( alias );
}
public String getOwnerAlias(String alias) {
return ( String ) alias2OwnerAlias.get( alias );
return alias2OwnerAlias.get( alias );
}
public Map getPropertyResultsMap(String alias) {
public Map<String, String[]> getPropertyResultsMap(String alias) {
return internalGetPropertyResultsMap( alias );
}
}
private Map internalGetPropertyResultsMap(String alias) {
NativeSQLQueryReturn rtn = ( NativeSQLQueryReturn ) alias2Return.get( alias );
if ( rtn instanceof NativeSQLQueryNonScalarReturn ) {
return ( ( NativeSQLQueryNonScalarReturn ) rtn ).getPropertyResultsMap();
}
else {
return null;
}
private Map<String, String[]> internalGetPropertyResultsMap(String alias) {
final NativeSQLQueryReturn rtn = alias2Return.get( alias );
return rtn.getNature() != NativeSQLQueryReturn.Nature.SCALAR ? NativeSQLQueryNonScalarReturn.class.cast( rtn ).getPropertyResultsMap() : null;
}
private boolean hasPropertyResultMap(String alias) {
Map propertyMaps = internalGetPropertyResultsMap( alias );
return propertyMaps != null && ! propertyMaps.isEmpty();
return CollectionHelper.isNotEmpty( propertyMaps );
}
public ResultAliasContext process() {
// 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 ) {
if ( queryReturns[i].getNature() != NativeSQLQueryReturn.Nature.SCALAR ) {
NativeSQLQueryNonScalarReturn rtn = ( NativeSQLQueryNonScalarReturn ) queryReturns[i];
alias2Return.put( rtn.getAlias(), rtn );
if ( rtn instanceof NativeSQLQueryJoinReturn ) {
if ( rtn.getNature() == NativeSQLQueryReturn.Nature.JOIN ) {
NativeSQLQueryJoinReturn fetchReturn = ( NativeSQLQueryJoinReturn ) rtn;
alias2OwnerAlias.put( fetchReturn.getAlias(), fetchReturn.getOwnerAlias() );
}
@ -175,30 +157,30 @@ public ResultAliasContext process() {
return new ResultAliasContext();
}
public List generateCustomReturns(boolean queryHadAliases) {
List customReturns = new ArrayList();
public List<Return> generateCustomReturns(boolean queryHadAliases) {
List<Return> customReturns = new ArrayList<Return>();
Map customReturnsByAlias = new HashMap();
for ( int i = 0; i < queryReturns.length; i++ ) {
if ( queryReturns[i] instanceof NativeSQLQueryScalarReturn ) {
if ( queryReturns[i].getNature() == NativeSQLQueryReturn.Nature.SCALAR ) {
NativeSQLQueryScalarReturn rtn = ( NativeSQLQueryScalarReturn ) queryReturns[i];
customReturns.add( new ScalarReturn( rtn.getType(), rtn.getColumnAlias() ) );
}
else if ( queryReturns[i] instanceof NativeSQLQueryRootReturn ) {
else if ( queryReturns[i].getNature() == NativeSQLQueryReturn.Nature.ROOT ) {
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 )
entityPropertyResultMaps.get( alias ),
alias2Persister.get( alias ),
alias2Suffix.get( alias )
);
}
else {
entityAliases = new ColumnEntityAliases(
( Map ) entityPropertyResultMaps.get( alias ),
( SQLLoadable ) alias2Persister.get( alias ),
( String ) alias2Suffix.get( alias )
entityPropertyResultMaps.get( alias ),
alias2Persister.get( alias ),
alias2Suffix.get( alias )
);
}
RootReturn customReturn = new RootReturn(
@ -210,37 +192,37 @@ else if ( queryReturns[i] instanceof NativeSQLQueryRootReturn ) {
customReturns.add( customReturn );
customReturnsByAlias.put( rtn.getAlias(), customReturn );
}
else if ( queryReturns[i] instanceof NativeSQLQueryCollectionReturn ) {
else if ( queryReturns[i].getNature() == NativeSQLQueryReturn.Nature.COLLECTION ) {
NativeSQLQueryCollectionReturn rtn = ( NativeSQLQueryCollectionReturn ) queryReturns[i];
String alias = rtn.getAlias();
SQLLoadableCollection persister = ( SQLLoadableCollection ) alias2CollectionPersister.get( alias );
SQLLoadableCollection persister = 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 )
collectionPropertyResultMaps.get( alias ),
alias2CollectionPersister.get( alias ),
alias2CollectionSuffix.get( alias )
);
if ( isEntityElements ) {
elementEntityAliases = new DefaultEntityAliases(
( Map ) entityPropertyResultMaps.get( alias ),
( SQLLoadable ) alias2Persister.get( alias ),
( String ) alias2Suffix.get( alias )
entityPropertyResultMaps.get( alias ),
alias2Persister.get( alias ),
alias2Suffix.get( alias )
);
}
}
else {
collectionAliases = new ColumnCollectionAliases(
( Map ) collectionPropertyResultMaps.get( alias ),
( SQLLoadableCollection ) alias2CollectionPersister.get( alias )
collectionPropertyResultMaps.get( alias ),
alias2CollectionPersister.get( alias )
);
if ( isEntityElements ) {
elementEntityAliases = new ColumnEntityAliases(
( Map ) entityPropertyResultMaps.get( alias ),
( SQLLoadable ) alias2Persister.get( alias ),
( String ) alias2Suffix.get( alias )
entityPropertyResultMaps.get( alias ),
alias2Persister.get( alias ),
alias2Suffix.get( alias )
);
}
}
@ -255,40 +237,40 @@ else if ( queryReturns[i] instanceof NativeSQLQueryCollectionReturn ) {
customReturns.add( customReturn );
customReturnsByAlias.put( rtn.getAlias(), customReturn );
}
else if ( queryReturns[i] instanceof NativeSQLQueryJoinReturn ) {
else if ( queryReturns[i].getNature() == NativeSQLQueryReturn.Nature.JOIN ) {
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 );
SQLLoadableCollection persister = alias2CollectionPersister.get( alias );
boolean isEntityElements = persister.getElementType().isEntityType();
CollectionAliases collectionAliases;
EntityAliases elementEntityAliases = null;
if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
collectionAliases = new GeneratedCollectionAliases(
( Map ) collectionPropertyResultMaps.get( alias ),
collectionPropertyResultMaps.get( alias ),
persister,
( String ) alias2CollectionSuffix.get( alias )
alias2CollectionSuffix.get( alias )
);
if ( isEntityElements ) {
elementEntityAliases = new DefaultEntityAliases(
( Map ) entityPropertyResultMaps.get( alias ),
( SQLLoadable ) alias2Persister.get( alias ),
( String ) alias2Suffix.get( alias )
entityPropertyResultMaps.get( alias ),
alias2Persister.get( alias ),
alias2Suffix.get( alias )
);
}
}
else {
collectionAliases = new ColumnCollectionAliases(
( Map ) collectionPropertyResultMaps.get( alias ),
collectionPropertyResultMaps.get( alias ),
persister
);
if ( isEntityElements ) {
elementEntityAliases = new ColumnEntityAliases(
( Map ) entityPropertyResultMaps.get( alias ),
( SQLLoadable ) alias2Persister.get( alias ),
( String ) alias2Suffix.get( alias )
entityPropertyResultMaps.get( alias ),
alias2Persister.get( alias ),
alias2Suffix.get( alias )
);
}
}
@ -305,16 +287,16 @@ else if ( queryReturns[i] instanceof NativeSQLQueryJoinReturn ) {
EntityAliases entityAliases;
if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
entityAliases = new DefaultEntityAliases(
( Map ) entityPropertyResultMaps.get( alias ),
( SQLLoadable ) alias2Persister.get( alias ),
( String ) alias2Suffix.get( alias )
entityPropertyResultMaps.get( alias ),
alias2Persister.get( alias ),
alias2Suffix.get( alias )
);
}
else {
entityAliases = new ColumnEntityAliases(
( Map ) entityPropertyResultMaps.get( alias ),
( SQLLoadable ) alias2Persister.get( alias ),
( String ) alias2Suffix.get( alias )
entityPropertyResultMaps.get( alias ),
alias2Persister.get( alias ),
alias2Suffix.get( alias )
);
}
customReturn = new EntityFetchReturn(
@ -334,7 +316,7 @@ else if ( queryReturns[i] instanceof NativeSQLQueryJoinReturn ) {
private SQLLoadable getSQLLoadable(String entityName) throws MappingException {
EntityPersister persister = factory.getEntityPersister( entityName );
if ( !(persister instanceof SQLLoadable) ) {
if ( !SQLLoadable.class.isInstance( persister ) ) {
throw new MappingException( "class persister is not SQLLoadable: " + entityName );
}
return (SQLLoadable) persister;
@ -349,17 +331,21 @@ private String generateCollectionSuffix() {
}
private void processReturn(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 );
switch ( rtn.getNature() ) {
case SCALAR:
processScalarReturn( (NativeSQLQueryScalarReturn) rtn );
break;
case ROOT:
processRootReturn( (NativeSQLQueryRootReturn) rtn );
break;
case COLLECTION:
processCollectionReturn( (NativeSQLQueryCollectionReturn) rtn );
break;
case JOIN:
processJoinReturn( (NativeSQLQueryJoinReturn) rtn );
break;
default:
throw new HibernateException( "unkonwn Query Return nature of " + rtn.getNature() );
}
}
@ -382,18 +368,18 @@ private void processRootReturn(NativeSQLQueryRootReturn rootReturn) {
* @param propertyResult
* @param persister
*/
private void addPersister(String alias, Map propertyResult, SQLLoadable persister) {
private void addPersister(String alias, Map<String, String[]> propertyResult, SQLLoadable persister) {
alias2Persister.put( alias, persister );
String suffix = generateEntitySuffix();
final String suffix = generateEntitySuffix();
LOG.tracev( "Mapping alias [{0}] to entity-suffix [{1}]", alias, suffix );
alias2Suffix.put( alias, suffix );
entityPropertyResultMaps.put( alias, propertyResult );
}
private void addCollection(String role, String alias, Map propertyResults) {
private void addCollection(String role, String alias, Map<String, String[]> propertyResults) {
SQLLoadableCollection collectionPersister = ( SQLLoadableCollection ) factory.getCollectionPersister( role );
alias2CollectionPersister.put( alias, collectionPersister );
String suffix = generateCollectionSuffix();
final String suffix = generateCollectionSuffix();
LOG.tracev( "Mapping alias [{0}] to collection-suffix [{1}]", alias, suffix );
alias2CollectionSuffix.put( alias, suffix );
collectionPropertyResultMaps.put( alias, propertyResults );
@ -404,20 +390,17 @@ private void addCollection(String role, String alias, Map propertyResults) {
}
}
private Map filter(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();
private Map<String, String[]> filter(Map<String, String[]> propertyResults) {
Map<String, String[]> result = new HashMap<String, String[]>( propertyResults.size() );
final String keyPrefix = "element.";
final int length = keyPrefix.length();
for ( final String path : propertyResults.keySet() ) {
if ( path.startsWith( keyPrefix ) ) {
result.put( path.substring( keyPrefix.length() ), element.getValue() );
String [] value = propertyResults.get( path );
result.put( path.substring( length ), value );
}
//todo add rest into result map w/o modification??
}
return result;
}
@ -425,7 +408,7 @@ private void processCollectionReturn(NativeSQLQueryCollectionReturn collectionRe
// we are initializing an owned collection
//collectionOwners.add( new Integer(-1) );
// collectionOwnerAliases.add( null );
String role = collectionReturn.getOwnerEntityName() + '.' + collectionReturn.getOwnerProperty();
final String role = collectionReturn.getOwnerEntityName() + '.' + collectionReturn.getOwnerProperty();
addCollection(
role,
collectionReturn.getAlias(),
@ -434,14 +417,13 @@ private void processCollectionReturn(NativeSQLQueryCollectionReturn collectionRe
}
private void processJoinReturn(NativeSQLQueryJoinReturn fetchReturn) {
String alias = fetchReturn.getAlias();
// if ( alias2Persister.containsKey( alias ) || collectionAliases.contains( alias ) ) {
final String alias = fetchReturn.getAlias();
if ( alias2Persister.containsKey( alias ) || alias2CollectionPersister.containsKey( alias ) ) {
// already been processed...
return;
}
String ownerAlias = fetchReturn.getOwnerAlias();
final String ownerAlias = fetchReturn.getOwnerAlias();
// Make sure the owner alias is known...
if ( !alias2Return.containsKey( ownerAlias ) ) {
@ -454,13 +436,12 @@ private void processJoinReturn(NativeSQLQueryJoinReturn fetchReturn) {
processReturn( ownerReturn );
}
SQLLoadable ownerPersister = ( SQLLoadable ) alias2Persister.get( ownerAlias );
SQLLoadable ownerPersister = 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;
@ -470,56 +451,4 @@ else if ( returnType.isEntityType() ) {
}
}
// public List getCollectionAliases() {
// return collectionAliases;
// }
//
// /*public List getCollectionOwners() {
// return collectionOwners;
// }*/
//
// public List getCollectionOwnerAliases() {
// return collectionOwnerAliases;
// }
//
// public List getCollectionPersisters() {
// return collectionPersisters;
// }
//
// public Map getAlias2Persister() {
// return alias2Persister;
// }
//
// /*public boolean isCollectionInitializer() {
// return isCollectionInitializer;
// }*/
//
//// public List getPersisters() {
//// return persisters;
//// }
//
// public Map getAlias2OwnerAlias() {
// return alias2OwnerAlias;
// }
//
// public List getScalarTypes() {
// return scalarTypes;
// }
// public List getScalarColumnAliases() {
// return scalarColumnAliases;
// }
//
// public List getPropertyResults() {
// return propertyResults;
// }
//
// public List getCollectionPropertyResults() {
// return collectionResults;
// }
//
//
// public Map getAlias2Return() {
// return alias2Return;
// }
}

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.internal.source.annotations.global;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@ -95,6 +94,7 @@ public static void bind(final AnnotationBindingContext bindingContext) {
private static void bindSqlResultSetMapping(final AnnotationBindingContext bindingContext, final AnnotationInstance annotation) {
entityAliasIndex = 0;
final String name = JandexHelper.getValue( annotation, "name", String.class );
LOG.debugf( "Binding @SqlResultSetMapping(name=%s)", name );
final ResultSetMappingDefinition definition = new ResultSetMappingDefinition( name );
for ( final AnnotationInstance entityResult : JandexHelper.getValue(
annotation,
@ -153,13 +153,20 @@ private static void bindEntityResult(final AnnotationBindingContext bindingConte
propertyResults.put( "class", new String[] { quotingNormalizedName } );
}
Set<String> uniqueReturnProperty = new HashSet<String>();
final Set<String> uniqueReturnProperty = new HashSet<String>();
for ( final AnnotationInstance fieldResult : JandexHelper.getValue(
entityResult,
"fields",
AnnotationInstance[].class
) ) {
bindFieldResult( bindingContext, targetEntityBinding, fieldResult, uniqueReturnProperty,propertyResults, definition );
bindFieldResult(
bindingContext,
targetEntityBinding,
fieldResult,
uniqueReturnProperty,
propertyResults,
definition
);
}
final NativeSQLQueryRootReturn result = new NativeSQLQueryRootReturn(
@ -178,24 +185,13 @@ private static void bindFieldResult(final AnnotationBindingContext bindingContex
final Map<String, String[]> propertyResults,
final ResultSetMappingDefinition definition) {
final String name = JandexHelper.getValue( fieldResult, "name", String.class );
if ( "class".equals( name ) ) {
throw new MappingException(
"class is not a valid property name to use in a @FieldResult, use @EntityResult(discriminatorColumn) instead"
);
}
if ( !uniqueReturnProperty.add( name ) ) {
throw new MappingException(
"duplicate @FieldResult for property " + name +
" on @Entity " + entityBinding.getEntity().getName() + " in " +definition.getName());
}
checkFieldNameisNotClass( name );
checkFieldNameUnique( entityBinding, uniqueReturnProperty, definition, name );
final String column = JandexHelper.getValue( fieldResult, "column", String.class );
final String quotingNormalizedColumnName = bindingContext.getMetadataImplementor().getObjectNameNormalizer()
.normalizeIdentifierQuoting( column );
if ( name.indexOf( '.' ) == -1 ) {
}
else {
final String quotingNormalizedColumnName = normalize( bindingContext, column );
if ( name.contains( "." ) ) {
int dotIndex = name.lastIndexOf( '.' );
String reducedName = name.substring( 0, dotIndex );
AttributeBinding attributeBinding = entityBinding.locateAttributeBinding( reducedName );
@ -203,7 +199,11 @@ private static void bindFieldResult(final AnnotationBindingContext bindingContex
CompositeAttributeBinding compositeAttributeBinding = CompositeAttributeBinding.class.cast(
attributeBinding
);
compositeAttributeBinding.attributeBindings();
boolean hasFollowers = false;
Iterable<AttributeBinding> attributeBindings = compositeAttributeBinding.attributeBindings();
for ( final AttributeBinding ab : attributeBindings ) {
ab.getAttribute().getName();
}
}
else if ( ManyToOneAttributeBinding.class.isInstance( attributeBinding ) ) {
ManyToOneAttributeBinding manyToOneAttributeBinding = ManyToOneAttributeBinding.class.cast(
@ -222,6 +222,23 @@ else if ( ManyToOneAttributeBinding.class.isInstance( attributeBinding ) ) {
insert( StringHelper.root( name ), quotingNormalizedColumnName, propertyResults );
}
private static void checkFieldNameUnique(EntityBinding entityBinding, Set<String> uniqueReturnProperty, ResultSetMappingDefinition definition, String name) {
if ( !uniqueReturnProperty.add( name ) ) {
throw new MappingException(
"duplicate @FieldResult for property " + name +
" on @Entity " + entityBinding.getEntity().getName() + " in " + definition.getName()
);
}
}
private static void checkFieldNameisNotClass(String name) {
if ( "class".equals( name ) ) {
throw new MappingException(
"class is not a valid property name to use in a @FieldResult, use @EntityResult(discriminatorColumn) instead"
);
}
}
private static void insert(String key, String value, Map<String, String[]> map) {
if ( map.containsKey( key ) ) {
String[] oldValues = map.get( key );
@ -238,9 +255,13 @@ private static void bindColumnResult(final AnnotationBindingContext bindingConte
final AnnotationInstance columnResult,
final ResultSetMappingDefinition definition) {
final String name = JandexHelper.getValue( columnResult, "name", String.class );
final String normalizedName = bindingContext.getMetadataImplementor()
.getObjectNameNormalizer()
.normalizeIdentifierQuoting( name );
final String normalizedName = normalize( bindingContext, name );
definition.addQueryReturn( new NativeSQLQueryScalarReturn( normalizedName, null ) );
}
private static String normalize(final AnnotationBindingContext bindingContext, String name) {
return bindingContext.getMetadataImplementor()
.getObjectNameNormalizer()
.normalizeIdentifierQuoting( name );
}
}