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

  1. Match the accessor to the declared collection interface: List -> getList, Set -> getSet, Collection/Bag -> getCollection
  2. Pass the exact declared element type, or use the untyped overloads (getCollection(name)) which skip the element-type check
  3. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/bc14db58ad575c6d. Report an issue: GitHub.