}
public void doSecondPass(Map persistentClasses) throws MappingException {
//TODO add parameters checkings
if ( ann == null ) return;
ResultSetMappingDefinition definition = new ResultSetMappingDefinition( ann.name() );
LOG.debugf( "Binding result set mapping: %s", definition.getName() );
int entityAliasIndex = 0;
for (EntityResult entity : ann.entities()) {
//TODO parameterize lock mode?
List<FieldResult> properties = new ArrayList<FieldResult>();
List<String> propertyNames = new ArrayList<String>();
for (FieldResult field : entity.fields()) {
//use an ArrayList cause we might have several columns per root property
String name = field.name();
if ( name.indexOf( '.' ) == -1 ) {
//regular property
properties.add( field );
propertyNames.add( name );
}
else {
/**
* Reorder properties
* 1. get the parent property
* 2. list all the properties following the expected one in the parent property
* 3. calculate the lowest index and insert the property
*/
PersistentClass pc = mappings.getClass( entity.entityClass().getName() );
if ( pc == null ) {
throw new MappingException(
"Entity not found " + entity.entityClass().getName()
+ " in SqlResultsetMapping " + ann.name()
);
}
int dotIndex = name.lastIndexOf( '.' );
String reducedName = name.substring( 0, dotIndex );
Iterator parentPropIter = getSubPropertyIterator( pc, reducedName );
List followers = getFollowers( parentPropIter, reducedName, name );
int index = propertyNames.size();
int followersSize = followers.size();
for (int loop = 0; loop < followersSize; loop++) {
String follower = (String) followers.get( loop );
int currentIndex = getIndexOfFirstMatchingProperty( propertyNames, follower );
index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
}
propertyNames.add( index, name );
properties.add( index, field );
}
}
Set<String> uniqueReturnProperty = new HashSet<String>();
Map<String, ArrayList<String>> propertyResultsTmp = new HashMap<String, ArrayList<String>>();
for ( Object property : properties ) {
final FieldResult propertyresult = ( FieldResult ) property;
final String name = propertyresult.name();
if ( "class".equals( name ) ) {
throw new MappingException(
"class is not a valid property name to use in a @FieldResult, use @Entity(discriminatorColumn) instead"
);
}
if ( uniqueReturnProperty.contains( name ) ) {
throw new MappingException(
"duplicate @FieldResult for property " + name +
" on @Entity " + entity.entityClass().getName() + " in " + ann.name()
);
}
uniqueReturnProperty.add( name );
final String quotingNormalizedColumnName = mappings.getObjectNameNormalizer()
.normalizeIdentifierQuoting( propertyresult.column() );
String key = StringHelper.root( name );
ArrayList<String> intermediateResults = propertyResultsTmp.get( key );
if ( intermediateResults == null ) {
intermediateResults = new ArrayList<String>();
propertyResultsTmp.put( key, intermediateResults );
}
intermediateResults.add( quotingNormalizedColumnName );
}
Map<String, String[]> propertyResults = new HashMap<String,String[]>();
for ( Map.Entry<String, ArrayList<String>> entry : propertyResultsTmp.entrySet() ) {
propertyResults.put(
entry.getKey(),
entry.getValue().toArray( new String[ entry.getValue().size() ] )
);
}
if ( !BinderHelper.isEmptyAnnotationValue( entity.discriminatorColumn() ) ) {
final String quotingNormalizedName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
entity.discriminatorColumn()
);
propertyResults.put( "class", new String[] { quotingNormalizedName } );
}
if ( propertyResults.isEmpty() ) {
propertyResults = java.util.Collections.emptyMap();
}
NativeSQLQueryRootReturn result = new NativeSQLQueryRootReturn(
"alias" + entityAliasIndex++,
entity.entityClass().getName(),
propertyResults,
LockMode.READ
);
definition.addQueryReturn( result );
}
for ( ColumnResult column : ann.columns() ) {
definition.addQueryReturn(
new NativeSQLQueryScalarReturn(
mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
column.name()
),
null