mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-17 08:35:13 +00:00
HHH-6491 Binding @SqlResultSetMapping
This commit is contained in:
parent
10a6425770
commit
1a3c584991
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -115,4 +115,9 @@ private int determineHashCode() {
|
||||
result = 31 * result + ( ownerProperty != null ? ownerProperty.hashCode() : 0 );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nature getNature() {
|
||||
return Nature.COLLECTION;
|
||||
}
|
||||
}
|
||||
|
@ -110,4 +110,9 @@ private int determineHashCode() {
|
||||
result = 31 * result + ( ownerProperty != null ? ownerProperty.hashCode() : 0 );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nature getNature() {
|
||||
return Nature.JOIN;
|
||||
}
|
||||
}
|
||||
|
@ -33,4 +33,9 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface NativeSQLQueryReturn {
|
||||
public static enum Nature{
|
||||
SCALAR, ROOT, COLLECTION, JOIN;
|
||||
}
|
||||
public Nature getNature();
|
||||
|
||||
}
|
||||
|
@ -101,4 +101,9 @@ private int determineHashCode() {
|
||||
result = 31 * result + ( returnEntityName != null ? returnEntityName.hashCode() : 0 );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nature getNature() {
|
||||
return Nature.ROOT;
|
||||
}
|
||||
}
|
||||
|
@ -79,4 +79,9 @@ private int determineHashCode() {
|
||||
result = 31 * result + ( columnAlias != null ? columnAlias.hashCode() : 0 );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nature getNature() {
|
||||
return Nature.SCALAR;
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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() );
|
||||
|
@ -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 );
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -73,5 +73,5 @@ public interface CustomQuery {
|
||||
*
|
||||
* @return List of return descriptors.
|
||||
*/
|
||||
public List getCustomQueryReturns();
|
||||
public List<Return> getCustomQueryReturns();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
// }
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user