{"record":{"id":"6cd0ca2c305a5cf7","repo":"hibernate/hibernate-orm","slug":"name-is-not-a-collectionattribute-attributec","errorCode":null,"errorMessage":"${name} is not a CollectionAttribute: ${attributeClass}","messagePattern":"(.+?) is not a CollectionAttribute: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java","lineNumber":483,"sourceCode":"\t// Bags\n\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\t@Nonnull\n\tpublic BagPersistentAttribute<? super J, ?> getCollection(@Nonnull String name) {\n\t\tvar attribute = findPluralAttribute( name );\n\t\tif ( attribute == null && getSuperType() != null ) {\n\t\t\tattribute = getSuperType().findPluralAttribute( name );\n\t\t}\n\t\tbasicCollectionCheck( attribute, name );\n\t\tassert attribute != null;\n\t\treturn (BagPersistentAttribute<J, ?>) attribute;\n\t}\n\n\tprivate void basicCollectionCheck(PluralAttribute<? super J, ?, ?> attribute, String name) {\n\t\tcheckNotNull( \"CollectionAttribute\", attribute, name );\n\t\tif ( ! BagPersistentAttribute.class.isAssignableFrom( attribute.getClass() ) ) {\n\t\t\tthrow new IllegalArgumentException( name + \" is not a CollectionAttribute: \" + attribute.getClass() );\n\t\t}\n\t}\n\n\t@Override\n\t@SuppressWarnings( \"unchecked\")\n\t@Nonnull\n\tpublic CollectionAttribute<J, ?> getDeclaredCollection(@Nonnull String name) {\n\t\tfinal var attribute = findDeclaredPluralAttribute( name );\n\t\tbasicCollectionCheck( attribute, name );\n\t\tassert attribute != null;\n\t\treturn ( CollectionAttribute<J, ?> ) attribute;\n\t}\n\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\t@Nonnull\n\tpublic <E> BagPersistentAttribute<? super J, E> getCollection(@Nonnull String name, @Nonnull Class<E> elementType) {\n\t\tfinal var attribute = findPluralAttribute( name );","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java#L465-L501","documentation":"getCollection(name)/getDeclaredCollection(name) found an attribute by that name, but it is not a bag-style CollectionPersistentAttribute — e.g. it is a Set, List, or Map attribute. Hibernate reports the actual attribute class so you can see which collection kind it really is.","triggerScenarios":"Calling getCollection(\"orders\") when Order.orders is declared as Set<Order> or List<Order>. The bag semantics of CollectionAttribute (unordered, no index, duplicates allowed) only fit Collection/Bag declarations.","commonSituations":"Declaring fields as Set or List (most common) and assuming getCollection is a generic 'any collection' accessor. Changing collection kinds during refactoring. Reading the error's attributeClass tells you the concrete type (SetPersistentAttributeImpl etc.) — map to the right accessor.","solutions":["Use the accessor matching the declaration: getSet for Set, getList for List, getMap for Map","Declare the field as java.util.Collection (or List without @OrderColumn semantics per JPA) if bag semantics are intended","Inspect attributeClass from the message to identify the real kind before fixing the call"],"exampleFix":"// before\nCollectionAttribute<Order, Item> items = orderType.getCollection(\"items\"); // items is List<Item> -> throws\n\n// after\nListAttribute<Order, Item> items = orderType.getList(\"items\");","handlingStrategy":"type-guard","validationCode":"var attr = type.findPluralAttribute(name); // or walk getAttributes()\nif (attr == null || !(attr instanceof org.hibernate.metamodel.model.domain.BagPersistentAttribute)) {\n    throw new IllegalArgumentException(name + \" is not a bag on \" + type.getTypeName());\n}","typeGuard":"static boolean isBag(ManagedType<?> type, String name) {\n    for (Attribute<?,?> a : type.getAttributes()) {\n        if (a.getName().equals(name)\n                && a instanceof org.hibernate.metamodel.model.domain.BagPersistentAttribute) return true;\n    }\n    return false;\n}","tryCatchPattern":"try {\n    return type.getCollection(name);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"is not a CollectionAttribute\")) {\n        // attribute is a Set/List/Map — use the matching accessor\n        throw e;\n    }\n    throw e;\n}","preventionTips":["Derive the accessor from attribute.getCollectionType() instead of assuming bag","Declare fields as List/Set/Map (most common) — plain Collection maps to a bag","The message names the real attribute class; use it to pick the right getter"],"tags":["hibernate","jpa-metamodel","collection-attribute","bag","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"}