hibernate/hibernate-orm · error · MappingException
Property join specified twice for join-return '" + ownerTabl
Error message
Property join specified twice for join-return '" + ownerTableAlias + "." + propertyPath + "' (" + registrationName + ") What it means
Hibernate stores join fetch descriptors per owner alias in a map keyed by property path. When a second <return-join/> resolves to the same (ownerTableAlias, propertyPath) pair, a JoinDescriptor already exists in that map and this MappingException is thrown. The mapping declares the same join twice, which Hibernate cannot disambiguate.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDescriptor.java:184
"Illegal <return-join/> property attribute: '" + fullPropertyPath + "' - "
+ " - should be in the form '{ownerAlias.joinedPropertyPath}' (" + registrationName + ")"
);
}
final String ownerTableAlias = fullPropertyPath.substring( 0, firstDot );
final String propertyPath = fullPropertyPath.substring( firstDot + 1 );
final String tableAlias = jaxbHbmJoin.getAlias();
Map<String, JoinDescriptor> joinDescriptorsForAlias = joinDescriptors.get( ownerTableAlias );
//noinspection Java8MapApi
if ( joinDescriptorsForAlias == null ) {
joinDescriptorsForAlias = new HashMap<>();
joinDescriptors.put( ownerTableAlias, joinDescriptorsForAlias );
}
final JoinDescriptor existing = joinDescriptorsForAlias.get( propertyPath );
if ( existing != null ) {
throw new MappingException(
"Property join specified twice for join-return '" + ownerTableAlias + "." + propertyPath
+ "' (" + registrationName + ")"
);
}
final JoinDescriptor joinDescriptor = new JoinDescriptor(
jaxbHbmJoin,
() -> joinDescriptors,
() -> fetchParentByAlias,
registrationName,
context
);
joinDescriptorsForAlias.put( propertyPath, joinDescriptor );
fetchParentByAlias.put( tableAlias, joinDescriptor );
}
/**View on GitHub (pinned to fad1729dce)
Solutions
- Delete the duplicate <return-join/> so each (ownerAlias, propertyPath) appears exactly once.
- If you needed the second join to map extra columns of the same association, keep one <return-join/> and add the extra columns as <return-property name="..." column="..."/> children of it.
- Give genuinely different joins different property paths (e.g. o.billingAddress vs o.shippingAddress).
Example fix
<!-- before: same join declared twice -->
<return-join alias="a1" property="o.address"/>
<return-join alias="a2" property="o.address"/>
<!-- after: one join, extra columns via return-property -->
<return-join alias="a1" property="o.address">
<return-property name="street" column="STREET"/>
<return-property name="city" column="CITY"/>
</return-join> Defensive patterns
Strategy: validation
Validate before calling
// detect duplicate joins while pre-parsing the mapping:
Set<String> seen = new HashSet<>();
for ( Element join : returnJoinElements ) {
String key = join.attributeValue( "property" ); // ownerAlias.propertyPath
if ( !seen.add( key ) ) {
throw new IllegalStateException( "Duplicate return-join for " + key );
}
} Try / catch
catch ( MappingException e ) {
if ( e.getMessage().startsWith( "Property join specified twice" ) ) {
// message contains ownerAlias.propertyPath and the mapping name; dedupe that join
}
} Prevention
- Keep one join per (owner, path); express extra columns via nested <return-property/> elements.
- After merging mapping files, search for repeated property= values within one query mapping.
- Cover each native query mapping with a boot test.
When it happens
Trigger: Two <return-join/> elements with the same property attribute (e.g. property="o.items" twice, possibly with different aliases); a copy-pasted join block left in place after adding a new one.
Common situations: Mapping files merged during team development where both authors added the same join; legacy mappings where additional columns for one join were expressed as a second identical join instead of nested <return-property/> elements.
Related errors
- Illegal <return-join/> property attribute: '" + fullProperty
- Illegal <return-join/> property attribute: '" + fullProperty
- <return-join/> did not specify alias [" + ownerTableAlias +
- Could not locate join-return owner by alias [" + ownerTableA
- HBM return-join ResultSet mapping must be used in conjunctio
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/66e3f3c73563728e.
Report an issue: GitHub.