{"record":{"id":"14723ec63fc603f0","repo":"hibernate/hibernate-orm","slug":"name-is-not-a-setattribute-attributeclass","errorCode":null,"errorMessage":"${name} is not a SetAttribute: ${attributeClass}","messagePattern":"(.+?) is not a SetAttribute: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java","lineNumber":537,"sourceCode":"\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// Set attributes\n\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\t@Nonnull\n\tpublic SetPersistentAttribute<? super J, ?> getSet(@Nonnull String name) {\n\t\tfinal var attribute = findPluralAttribute( name );\n\t\tbasicSetCheck( attribute, name );\n\t\tassert attribute != null;\n\t\treturn (SetPersistentAttribute<? super J, ?>) attribute;\n\t}\n\n\tprivate void basicSetCheck(PluralAttribute<? super J, ?, ?> attribute, String name) {\n\t\tcheckNotNull( \"SetAttribute\", attribute, name );\n\t\tif ( ! SetPersistentAttribute.class.isAssignableFrom( attribute.getClass() ) ) {\n\t\t\tthrow new IllegalArgumentException( name + \" is not a SetAttribute: \" + attribute.getClass() );\n\t\t}\n\t}\n\n\t@Override\n\t@SuppressWarnings( \"unchecked\")\n\t@Nonnull\n\tpublic SetPersistentAttribute<J, ?> getDeclaredSet(@Nonnull String name) {\n\t\tfinal var attribute = findDeclaredPluralAttribute( name );\n\t\tbasicSetCheck( attribute, name );\n\t\tassert attribute != null;\n\t\treturn (SetPersistentAttribute<J, ?>) attribute;\n\t}\n\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\t@Nonnull\n\tpublic <E> SetAttribute<? super J, E> getSet(@Nonnull String name, @Nonnull Class<E> elementType) {\n\t\tfinal var attribute = findPluralAttribute( name );","sourceCodeStart":519,"sourceCodeEnd":555,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractManagedType.java#L519-L555","documentation":"getSet(name)/getDeclaredSet(name) found the attribute but its concrete class is not a SetPersistentAttribute — typically it is a Bag (Collection), List, or Map attribute implementation. Hibernate includes the actual attribute class in the message.","triggerScenarios":"Calling getSet(\"tags\") on a field declared as Collection<String>, List<String>, or Map<...>. Set semantics (unique elements) only exist for Set/PersistentSet mappings.","commonSituations":"Field declared as List or Collection while the code assumes a Set; switching collection types during refactoring without updating metamodel accessors.","solutions":["Use getList/getCollection/getMap according to the actual declaration","Change the entity field to java.util.Set if set semantics are wanted (and re-check equals/hashCode of the element type)","Derive the accessor dynamically from attribute.getCollectionType()"],"exampleFix":"// before\nSetPersistentAttribute<Post, String> tags = postType.getSet(\"tags\"); // List<String> field -> throws\n\n// after\nListPersistentAttribute<Post, String> tags = postType.getList(\"tags\");\n// or change field: Set<String> tags;","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.SetPersistentAttribute)) {\n    throw new IllegalArgumentException(name + \" is not a Set on \" + type.getTypeName());\n}","typeGuard":"static boolean isSetAttr(ManagedType<?> type, String name) {\n    for (Attribute<?,?> a : type.getAttributes()) {\n        if (a.getName().equals(name)\n                && a instanceof org.hibernate.metamodel.model.domain.SetPersistentAttribute) return true;\n    }\n    return false;\n}","tryCatchPattern":"try {\n    return type.getSet(name);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"is not a SetAttribute\")) {\n        return null; // or route to getList/getCollection based on real kind\n    }\n    throw e;\n}","preventionTips":["Set accessors only work on Set-mapped fields","When refactoring collection kinds, grep for getSet( call sites","Log the actual attributeClass from the exception to pick the correct accessor"],"tags":["hibernate","jpa-metamodel","set-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"}