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 (list) reference [%s] relative to %s
What it means
AbstractSqmFrom.joinList(attributeName, joinType) requires a ListPersistentAttribute, i.e. a java.util.List mapped with @OrderColumn. A List mapped without @OrderColumn is modeled by Hibernate as a bag (BagPersistentAttribute), not a list, so joinList on it throws IllegalArgumentException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/AbstractSqmFrom.java:604
}
@Nonnull
@Override
@SuppressWarnings("unchecked")
public <Y> SqmListJoin<T, Y> joinList(@Nonnull String attributeName, @Nonnull JoinType jt) {
final var joinedPathSource = getReferencedPathSource().getSubPathSource( attributeName );
if ( joinedPathSource instanceof ListPersistentAttribute ) {
final var join = buildListJoin(
(ListPersistentAttribute<T, Y>) 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 (list) reference [%s] relative to %s",
attributeName,
joinedPathSource,
getNavigablePath()
)
);
}
@Nonnull
@Override
public <K, V> SqmMapJoin<T, K, V> joinMap(@Nonnull String attributeName) {
return joinMap( attributeName, JoinType.INNER );
}
@Nonnull
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- For a List without @OrderColumn use joinCollection(attributeName, joinType) instead.
- If positional semantics are required, map the attribute with @OrderColumn so it becomes a true ListPersistentAttribute.
- Use the typed overload join(ListAttribute) from the metamodel to make the mismatch a compile-time issue.
Example fix
// before customerRoot.joinList( "orders", JoinType.INNER ); // List<Order> without @OrderColumn -> bag // after customerRoot.joinCollection( "orders", JoinType.INNER );
Defensive patterns
Strategy: type-guard
Type guard
static boolean isOrderedList(ManagedType<?> type, String attr) {
Attribute<?, ?> a = type.getAttribute( attr );
return a instanceof org.hibernate.metamodel.model.domain.ListPersistentAttribute; // @OrderColumn lists only
} Prevention
- Remember: java.util.List without @OrderColumn is a bag in Hibernate — use joinCollection for it.
- Guard joinList with a ListPersistentAttribute check (not just java.util.List in the Java type).
- If positional list semantics are required, add @OrderColumn to the mapping.
When it happens
Trigger: root.joinList("items", JoinType.LEFT) when items is List<Item> without @OrderColumn (bag); joinList on Set/Collection/Map/singular attributes.
Common situations: The classic case: entity uses List<Order> orders with no @OrderColumn, and query code calls joinList because the Java type is a List; also removal of @OrderColumn during mapping cleanup breaking existing criteria queries.
Related errors
- Attribute '{}' is annotated '@Bag' and may not also be annot
- Bag is not a list:
- Passed attribute name [%s] did not correspond to a collectio
- Passed attribute name [%s] did not correspond to a collectio
- Passed attribute name [%s] did not correspond to a collectio
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/5b78961877e39aa8.
Report an issue: GitHub.