hibernate/hibernate-orm · error · IllegalArgumentException
Passed attribute name [%s] did not correspond to a collectio
Error message
Passed attribute name [%s] did not correspond to a collection (map) reference [%s] relative to %s
What it means
AbstractSqmFrom.joinMap(attributeName, joinType) requires the resolved attribute to be a MapPersistentAttribute (java.util.Map mapping with key/value semantics). Any other plural or singular kind throws IllegalArgumentException naming the attribute, the resolved source and the navigable path.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/AbstractSqmFrom.java:637
}
@Nonnull
@Override
@SuppressWarnings("unchecked")
public <K, V> SqmMapJoin<T, K, V> joinMap(@Nonnull String attributeName, @Nonnull JoinType jt) {
final var joinedPathSource = getReferencedPathSource().getSubPathSource( attributeName );
if ( joinedPathSource instanceof MapPersistentAttribute<?, ?, ?> ) {
final var join = buildMapJoin(
(MapPersistentAttribute<T, K, V>) joinedPathSource,
SqmJoinType.from( jt ),
false
);
addSqmJoin( join );
return join;
}
throw new IllegalArgumentException(
String.format(
Locale.ROOT,
"Passed attribute name [%s] did not correspond to a collection (map) reference [%s] relative to %s",
attributeName,
joinedPathSource,
getNavigablePath()
)
);
}
@Nonnull
@Override
public <R> SqmEntityJoin<T, R> join(@Nonnull Class<R> entityJavaType) {
return join( nodeBuilder().getDomainModel().entity( entityJavaType ) );
}
@Nonnull
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- Use joinCollection/joinSet/joinList/join matching the actual container type.
- Use the typed overload join(MapAttribute) from the metamodel for compile-time safety.
- Check the metamodel attribute kind before choosing the method.
Example fix
// before productRoot.joinMap( "specs", JoinType.LEFT ); // specs is List<Spec> // after productRoot.joinList( "specs", JoinType.LEFT );
Defensive patterns
Strategy: type-guard
Type guard
static boolean isMap(ManagedType<?> type, String attr) {
return type.getAttribute( attr ) instanceof jakarta.persistence.metamodel.MapAttribute;
} Prevention
- Use the typed join(MapAttribute) overload when the metamodel object is available.
- Check the attribute kind before string-based joinMap in generic builders.
- After refactoring Map fields to other containers, update the corresponding join method.
When it happens
Trigger: root.joinMap("translations", JoinType.INNER) when translations is Collection/List/Set; joinMap on a @ManyToOne or basic attribute.
Common situations: Changing a Map field to a List during refactoring; generic code assuming map semantics; keys modeled via @MapKey and then the field changed to a collection type.
Related errors
- Passed attribute name [%s] did not correspond to a collectio
- Passed attribute name [%s] did not correspond to a collectio
- Passed attribute [%s] did not correspond to a joinable refer
- Illegal empty CTE name
- Illegal CTE name [%s]. Names must start with an alphabetic c
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/6f8f78c98a22ce52.
Report an issue: GitHub.