{"record":{"id":"a7ad059de3dbe4af","repo":"hibernate/hibernate-orm","slug":"not-a-singular-attribute-node","errorCode":null,"errorMessage":"Not a singular attribute node","messagePattern":"Not a singular attribute node","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/graph/internal/AttributeNodeImpl.java","lineNumber":201,"sourceCode":"\t\treturn attribute;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic SubGraphImplementor<E> addValueSubgraph() {\n\t\tverifyMutability();\n\t\tsetFetchType( FetchType.EAGER );\n\t\t// this one is intentionally lenient and disfavored\n\t\tif ( valueSubgraph == null ) {\n\t\t\tvalueSubgraph = new SubGraphImpl<>( asManagedType( valueGraphType ), true );\n\t\t}\n\t\treturn valueSubgraph;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic SubGraphImplementor<J> addSingularSubgraph() {\n\t\tthrow new UnsupportedOperationException(\"Not a singular attribute node\");\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic SubGraphImplementor<E> addElementSubgraph() {\n\t\tthrow new UnsupportedOperationException( \"Not a collection-valued attribute node\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic SubGraphImplementor<K> addKeySubgraph() {\n\t\tthrow new UnsupportedOperationException( \"Not a Map-valued attribute node\" );\n\t}\n\n\tprotected void checkToOne() {\n\t\tfinal Attribute.PersistentAttributeType attributeType = attribute.getPersistentAttributeType();\n\t\tif ( attributeType != MANY_TO_ONE && attributeType != ONE_TO_ONE && attributeType != EMBEDDED ) {\n\t\t\tthrow new CannotContainSubGraphException( \"Attribute '\" + attribute.getName() + \"' is not a to-one association\" );","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/graph/internal/AttributeNodeImpl.java#L183-L219","documentation":"AttributeNodeImpl is sealed into singular, plural and map node kinds, and each kind supports only the subgraph methods matching its attribute: addSingularSubgraph() is implemented solely on SingularAttributeNodeImpl. Calling it on a node for a collection attribute (PluralAttributeNodeImpl / MapAttributeNodeImpl) hits the base-class implementation and throws UnsupportedOperationException.","triggerScenarios":"Calling node.addSingularSubgraph() — or the convenience addSubgraph(), which delegates to addSingularSubgraph() — on an attribute node obtained for a @OneToMany, @ManyToMany or @ElementCollection attribute, e.g. graph.addAttributeNode(\"items\").addSingularSubgraph().","commonSituations":"Generic graph-building code that unconditionally calls addSubgraph for every node; refactoring a to-one into a to-many without updating graph code; adopting the JPA 3.2 addSingularSubgraph/addElementSubgraph pair and calling the wrong variant.","solutions":["For collection attributes use addElementSubgraph() (elements) or, for Maps, addKeySubgraph() (keys)","For to-one/embedded attributes use addSingularSubgraph() (or addSubgraph())","In generic builders, branch on the metamodel: if (attr instanceof PluralAttribute) addElementSubgraph else addSingularSubgraph","Check the attribute's PersistentAttributeType before choosing the subgraph method"],"exampleFix":"// before — singular subgraph on a collection attribute\ngraph.addAttributeNode(\"items\").addSingularSubgraph(); // items is @OneToMany → throws\n\n// after — subgraph over the collection elements\ngraph.addAttributeNode(\"items\")\n     .addElementSubgraph()\n     .addAttributeNode(\"product\");","handlingStrategy":"type-guard","validationCode":"// Dispatch on the attribute kind instead of calling addSingularSubgraph unconditionally\nif (isSingular(node.getAttribute())) {\n    node.addSingularSubgraph().addAttributeNode(\"name\");\n}\nelse {\n    node.addElementSubgraph().addAttributeNode(\"name\");\n}","typeGuard":"static boolean isSingular(Attribute<?, ?> attr) {\n    return !(attr instanceof jakarta.persistence.metamodel.PluralAttribute<?, ?, ?>);\n}","tryCatchPattern":null,"preventionTips":["Dispatch on the metamodel kind (PluralAttribute vs singular) in generic graph code","Prefer the explicit addSingularSubgraph/addElementSubgraph pair over the legacy addSubgraph","Write one small graph-builder helper that picks the right method per attribute and reuse it"],"tags":["hibernate","entity-graph","subgraph","attribute-node","jpa"],"backgroundTag":"entity-graph-misuse","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}