hibernate/hibernate-orm · error · IllegalArgumentException
No plural attribute named '{}' and of element type '{}' in t
Error message
No plural attribute named '{}' and of element type '{}' in type '{}' What it means
The plural-attribute getters (getCollection/getSet/getList/getMap with element type) failed the three-part check in checkTypeForPluralAttributes: the attribute was not found by name, or its bindable (element) Java type differs from the requested Class (strict equals, not assignability), or its collection type (BAG/SET/LIST/MAP) does not match the accessor used.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java:436
}
}
@Override
@Nullable
public SqmPluralPersistentAttribute<J, ?, ?> findDeclaredPluralAttribute(@Nonnull String name) {
return declaredPluralAttributes == null ? null : declaredPluralAttributes.get( name );
}
private <E> void checkTypeForPluralAttributes(
String attributeType,
PluralAttribute<?,?,?> attribute,
String name,
Class<E> elementType,
PluralAttribute.CollectionType collectionType) {
if ( attribute == null
|| elementType != null && !attribute.getBindableJavaType().equals( elementType )
|| attribute.getCollectionType() != collectionType ) {
throw new IllegalArgumentException(
"No plural attribute named '" + name
+ ( elementType != null ? "' and of element type '" + elementType.getName() : "" )
+ "' in type '" + hibernateTypeName + "'"
);
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Generic attributes
@Override
@Nullable
public SqmPersistentAttribute<? super J, ?> findConcreteGenericAttribute(@Nonnull String name) {
final var attribute = findDeclaredConcreteGenericAttribute( name );
return attribute == null && getSuperType() != null
? getSuperType().findDeclaredConcreteGenericAttribute( name )
: attribute;View on GitHub (pinned to fad1729dce)
Solutions
- Match the accessor to the declared collection interface: List -> getList, Set -> getSet, Collection/Bag -> getCollection
- Pass the exact declared element type, or use the untyped overloads (getCollection(name)) which skip the element-type check
- Check the attribute first with findPluralAttribute(name) and read getBindableJavaType()/getCollectionType()
Example fix
// before
var items = orderType.getCollection("items", SpecialItem.class); // declared element: Item -> equals fails
// after
var items = orderType.getCollection("items", Item.class);
// or untyped: orderType.getCollection("items"); Defensive patterns
Strategy: validation
Validate before calling
// Verify kind + element type before the typed call
var found = StreamSupport.stream(type.getAttributes().spliterator(), false)
.filter(a -> a.getName().equals(name)).findFirst().orElseThrow();
if (found instanceof PluralAttribute<?,?,?> pa
&& pa.getCollectionType() == javax.persistence.metamodel.PluralAttribute.CollectionType.SET
&& pa.getElementType().getJavaType().equals(elementType)) {
return type.getSet(name, elementType);
} Type guard
static boolean isPluralOf(ManagedType<?> type, String name,
PluralAttribute.CollectionType kind, Class<?> elementType) {
for (Attribute<?,?> a : type.getAttributes()) {
if (a instanceof PluralAttribute<?,?,?> pa && a.getName().equals(name)) {
return pa.getCollectionType() == kind
&& pa.getBindableJavaType().equals(elementType);
}
}
return false;
} Try / catch
try {
return type.getCollection(name, elementType);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("No plural attribute named")) {
// wrong name, wrong element type, or wrong collection kind
throw new NoSuchFieldException(name + " as plural on " + type.getTypeName());
}
throw e;
} Prevention
- The element-type check is strict equals — subclasses of the element type are rejected
- Match accessor to kind: LIST->getList, SET->getSet, MAP->getMap, bag->getCollection
- Or use the untyped overloads (getSet(name)) which skip the element check
When it happens
Trigger: Calling getCollection("items", OrderItem.class) when the attribute is a List (collectionType LIST != COLLECTION semantics of the accessor), or when the element type is a subclass of the requested type (equals fails even for valid subtypes), or misspelled/inherited name.
Common situations: Element-type polymorphism: declaring Collection<Item> but storing SpecialItem — the strict equals check rejects the subtype. Switching a field between List and Set during refactoring. Using getCollection for lists (JPA treats LIST as its own collection type here).
Related errors
- ${name} is not a SetAttribute: ${attributeClass}
- ${name} is not a ListAttribute: ${attributeClass}
- ${name} is not a MapAttribute: ${attributeClass}
- Attribute '%s.%s' of type '%s' is annotated '@Bag' (bags are
- Attribute [%s#%s : %s] not castable to requested type [%s]
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/bc14db58ad575c6d.
Report an issue: GitHub.