{"record":{"id":"bc14db58ad575c6d","repo":"hibernate/hibernate-orm","slug":"no-plural-attribute-named-and-of-element-type","errorCode":null,"errorMessage":"No plural attribute named '{}' and of element type '{}' in type '{}'","messagePattern":"No plural attribute named '(.+?)' and of element type '(.+?)' in type '(.+?)'","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java","lineNumber":436,"sourceCode":"\t\t}\n\t}\n\n\t@Override\n\t@Nullable\n\tpublic SqmPluralPersistentAttribute<J, ?, ?> findDeclaredPluralAttribute(@Nonnull String name) {\n\t\treturn declaredPluralAttributes == null ? null : declaredPluralAttributes.get( name );\n\t}\n\n\tprivate <E> void checkTypeForPluralAttributes(\n\t\t\tString attributeType,\n\t\t\tPluralAttribute<?,?,?> attribute,\n\t\t\tString name,\n\t\t\tClass<E> elementType,\n\t\t\tPluralAttribute.CollectionType collectionType) {\n\t\tif ( attribute == null\n\t\t\t\t|| elementType != null && !attribute.getBindableJavaType().equals( elementType )\n\t\t\t\t|| attribute.getCollectionType() != collectionType ) {\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\"No plural attribute named '\" + name\n\t\t\t\t\t+ ( elementType != null ? \"' and of element type '\" + elementType.getName() : \"\" )\n\t\t\t\t\t+ \"' in type '\" + hibernateTypeName + \"'\"\n\t\t\t);\n\t\t}\n\t}\n\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// Generic attributes\n\n\t@Override\n\t@Nullable\n\tpublic SqmPersistentAttribute<? super J, ?> findConcreteGenericAttribute(@Nonnull String name) {\n\t\tfinal var attribute = findDeclaredConcreteGenericAttribute( name );\n\t\treturn attribute == null && getSuperType() != null\n\t\t\t\t? getSuperType().findDeclaredConcreteGenericAttribute( name )\n\t\t\t\t: attribute;","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java#L418-L454","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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()"],"exampleFix":"// before\nvar items = orderType.getCollection(\"items\", SpecialItem.class); // declared element: Item -> equals fails\n\n// after\nvar items = orderType.getCollection(\"items\", Item.class);\n// or untyped: orderType.getCollection(\"items\");","handlingStrategy":"validation","validationCode":"// Verify kind + element type before the typed call\nvar found = StreamSupport.stream(type.getAttributes().spliterator(), false)\n        .filter(a -> a.getName().equals(name)).findFirst().orElseThrow();\nif (found instanceof PluralAttribute<?,?,?> pa\n        && pa.getCollectionType() == javax.persistence.metamodel.PluralAttribute.CollectionType.SET\n        && pa.getElementType().getJavaType().equals(elementType)) {\n    return type.getSet(name, elementType);\n}","typeGuard":"static boolean isPluralOf(ManagedType<?> type, String name,\n        PluralAttribute.CollectionType kind, Class<?> elementType) {\n    for (Attribute<?,?> a : type.getAttributes()) {\n        if (a instanceof PluralAttribute<?,?,?> pa && a.getName().equals(name)) {\n            return pa.getCollectionType() == kind\n                && pa.getBindableJavaType().equals(elementType);\n        }\n    }\n    return false;\n}","tryCatchPattern":"try {\n    return type.getCollection(name, elementType);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"No plural attribute named\")) {\n        // wrong name, wrong element type, or wrong collection kind\n        throw new NoSuchFieldException(name + \" as plural on \" + type.getTypeName());\n    }\n    throw e;\n}","preventionTips":["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"],"tags":["hibernate","jpa-metamodel","plural-attribute","collection-type","type-mismatch"],"backgroundTag":"jpa-metamodel-collection-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}