hibernate/hibernate-orm · error · MappingException
<return-collection/> did not specify alias - %s
Error message
<return-collection/> did not specify alias - %s
What it means
The CollectionResultDescriptor constructor splits the role attribute into entity name and collection name, builds the collectionPath, then reads hbmCollectionReturn.getAlias(). A <return-collection/> without an alias attribute yields null and this MappingException is thrown, formatted with the resolved collection path. The alias is required because <return-join/> fetches hang off it.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDescriptor.java:858
private final Supplier<Map<String, Map<String, JoinDescriptor>>> joinDescriptorsAccess;
private final List<HbmFetchDescriptor> propertyFetchDescriptors;
public CollectionResultDescriptor(
JaxbHbmNativeQueryCollectionLoadReturnType hbmCollectionReturn,
Supplier<Map<String, Map<String, JoinDescriptor>>> joinDescriptorsAccess,
String registrationName,
MetadataBuildingContext context) {
final String role = hbmCollectionReturn.getRole();
final int dotIndex = role.indexOf( '.' );
final String entityName = role.substring( 0, dotIndex );
final var metadataCollector = context.getMetadataCollector();
final String fullEntityName = metadataCollector.getImports().get( entityName );
collectionPath = new NavigablePath(
fullEntityName + "." + role.substring( dotIndex + 1 )
);
tableAlias = hbmCollectionReturn.getAlias();
if ( tableAlias == null ) {
throw new MappingException(
String.format(
Locale.ROOT,
"<return-collection/> did not specify alias - %s",
collectionPath
)
);
}
BootQueryLogging.BOOT_QUERY_LOGGER.tracef(
"Creating CollectionResultDescriptor (%s : %s)",
tableAlias,
collectionPath
);
// this.lockMode = hbmCollectionReturn.getLockMode();
this.joinDescriptorsAccess = joinDescriptorsAccess;
propertyFetchDescriptors = extractPropertyFetchDescriptors(View on GitHub (pinned to fad1729dce)
Solutions
- Add the alias attribute: <return-collection alias="i" role="Order.items"/>.
- Ensure the alias is the one referenced by any <return-join property="i..."/> in the same mapping.
Example fix
<!-- before --> <return-collection role="Order.items"/> <!-- after --> <return-collection alias="i" role="Order.items"/>
Defensive patterns
Strategy: validation
Validate before calling
String alias = returnCollectionElement.attributeValue( "alias" );
if ( alias == null || alias.isBlank() ) {
throw new IllegalStateException( "return-collection role=" + returnCollectionElement.attributeValue( "role" ) + " needs an alias" );
} Try / catch
catch ( MappingException e ) {
if ( e.getMessage().startsWith( "<return-collection/> did not specify alias" ) ) {
// message contains the resolved collection path; add alias="..." to that element
}
} Prevention
- Every return element type (return, return-collection, return-join) requires an alias; treat it as mandatory in templates and reviews.
- Automate an XML schema/lint pass over hbm.xml in the build.
When it happens
Trigger: <return-collection role="Order.items"/> with no alias attribute; tooling that emits the role but skips the alias.
Common situations: Hand-written legacy mappings; migrating old native queries where aliases were optional in different Hibernate versions.
Related errors
- Cannot combine other returns with a collection return (" + r
- Entity <return/> mapping did not specify alias
- HBM return-collection ResultSet mapping cannot define entity
- Illegal <return-join/> property attribute: '" + fullProperty
- Entity <return/> mapping did not specify entity name
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/b996ecc0ebea1855.
Report an issue: GitHub.