{"record":{"id":"c6d7e5acf5f27baf","repo":"hibernate/hibernate-orm","slug":"name-is-not-a-listattribute-attributeclass","errorCode":null,"errorMessage":"${name} is not a ListAttribute: ${attributeClass}","messagePattern":"(.+?) is not a ListAttribute: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java","lineNumber":591,"sourceCode":"\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// List attributes\n\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\t@Nonnull\n\tpublic ListPersistentAttribute<? super J, ?> getList(@Nonnull String name) {\n\t\tfinal var attribute = findPluralAttribute( name );\n\t\tbasicListCheck( attribute, name );\n\t\tassert attribute != null;\n\t\treturn (ListPersistentAttribute<? super J, ?>) attribute;\n\t}\n\n\tprivate void basicListCheck(PluralAttribute<? super J, ?, ?> attribute, String name) {\n\t\tcheckNotNull( \"ListAttribute\", attribute, name );\n\t\tif ( ! ListPersistentAttribute.class.isAssignableFrom( attribute.getClass() ) ) {\n\t\t\tthrow new IllegalArgumentException( name + \" is not a ListAttribute: \" + attribute.getClass() );\n\t\t}\n\t}\n\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\t@Nonnull\n\tpublic ListPersistentAttribute<J, ?> getDeclaredList(@Nonnull String name) {\n\t\tfinal var attribute = findDeclaredPluralAttribute( name );\n\t\tbasicListCheck( attribute, name );\n\t\tassert attribute != null;\n\t\treturn (ListPersistentAttribute<J, ?>) attribute;\n\t}\n\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\t@Nonnull\n\tpublic <E> ListAttribute<? super J, E> getList(@Nonnull String name, @Nonnull Class<E> elementType) {\n\t\tfinal var attribute = findPluralAttribute( name );","sourceCodeStart":573,"sourceCodeEnd":609,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java#L573-L609","documentation":"getList(name)/getDeclaredList(name) found the attribute but it is not a ListPersistentAttribute — it is a bag (plain Collection), Set, or Map attribute. The message prints the concrete attribute class so you can tell which kind it is.","triggerScenarios":"Calling getList(\"lines\") when the field is declared as Collection<OrderLine> (mapped as a bag, not a list) or as a Set. In JPA, Collection fields map to bags unless declared List; only List fields support ordered/indexed semantics.","commonSituations":"Declaring the field as Collection and expecting list behavior; JPA bag-vs-list distinction surprises (bags allow duplicates and no index; @OrderColumn requires List).","solutions":["Declare the field as java.util.List (add @OrderColumn if an index column is needed) when list semantics are intended","Or call getCollection(name) for bag-mapped Collection fields","Check the message's attributeClass to confirm the real mapping kind"],"exampleFix":"// before\nListPersistentAttribute<Order, Line> lines = orderType.getList(\"lines\"); // Collection<Line> bag -> throws\n\n// after\n// either: private List<Line> lines;  (+ @OrderColumn if needed)\n// or:    CollectionAttribute<Order, Line> lines = orderType.getCollection(\"lines\");","handlingStrategy":"type-guard","validationCode":"var attr = StreamSupport.stream(type.getAttributes().spliterator(), false)\n        .filter(a -> a.getName().equals(name)).findFirst().orElse(null);\nif (!(attr instanceof org.hibernate.metamodel.model.domain.ListPersistentAttribute)) {\n    throw new IllegalArgumentException(name + \" is not a List on \" + type.getTypeName());\n}","typeGuard":"static boolean isListAttr(ManagedType<?> type, String name) {\n    for (Attribute<?,?> a : type.getAttributes()) {\n        if (a.getName().equals(name)\n                && a instanceof org.hibernate.metamodel.model.domain.ListPersistentAttribute) return true;\n    }\n    return false;\n}","tryCatchPattern":"try {\n    return type.getList(name);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"is not a ListAttribute\")) {\n        // Collection-mapped bag: use getCollection(name)\n        return type.getCollection(name);\n    }\n    throw e;\n}","preventionTips":["JPA maps Collection fields to bags — declare List if you need list semantics","Add @OrderColumn when index positions matter","One collection-kind decision per relationship; document it next to the field"],"tags":["hibernate","jpa-metamodel","list-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"}