hibernate/hibernate-orm · error · UnsupportedOperationException
Not a singular attribute node
Error message
Not a singular attribute node
What it means
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.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/graph/internal/AttributeNodeImpl.java:201
return attribute;
}
@Override
@Nonnull
public SubGraphImplementor<E> addValueSubgraph() {
verifyMutability();
setFetchType( FetchType.EAGER );
// this one is intentionally lenient and disfavored
if ( valueSubgraph == null ) {
valueSubgraph = new SubGraphImpl<>( asManagedType( valueGraphType ), true );
}
return valueSubgraph;
}
@Override
@Nonnull
public SubGraphImplementor<J> addSingularSubgraph() {
throw new UnsupportedOperationException("Not a singular attribute node");
}
@Override
@Nonnull
public SubGraphImplementor<E> addElementSubgraph() {
throw new UnsupportedOperationException( "Not a collection-valued attribute node" );
}
@Override
@Nonnull
public SubGraphImplementor<K> addKeySubgraph() {
throw new UnsupportedOperationException( "Not a Map-valued attribute node" );
}
protected void checkToOne() {
final Attribute.PersistentAttributeType attributeType = attribute.getPersistentAttributeType();
if ( attributeType != MANY_TO_ONE && attributeType != ONE_TO_ONE && attributeType != EMBEDDED ) {
throw new CannotContainSubGraphException( "Attribute '" + attribute.getName() + "' is not a to-one association" );View on GitHub (pinned to fad1729dce)
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
Example fix
// before — singular subgraph on a collection attribute
graph.addAttributeNode("items").addSingularSubgraph(); // items is @OneToMany → throws
// after — subgraph over the collection elements
graph.addAttributeNode("items")
.addElementSubgraph()
.addAttributeNode("product"); Defensive patterns
Strategy: type-guard
Validate before calling
// Dispatch on the attribute kind instead of calling addSingularSubgraph unconditionally
if (isSingular(node.getAttribute())) {
node.addSingularSubgraph().addAttributeNode("name");
}
else {
node.addElementSubgraph().addAttributeNode("name");
} Type guard
static boolean isSingular(Attribute<?, ?> attr) {
return !(attr instanceof jakarta.persistence.metamodel.PluralAttribute<?, ?, ?>);
} Prevention
- 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
When it happens
Trigger: 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().
Common situations: 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.
Related errors
- Not a collection-valued attribute node
- Not a Map-valued attribute node
- Attribute '{}' is not a to-one association
- Attribute '{}' is of type '{}' which is not a managed type
- No node for attribute: {}
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/a7ad059de3dbe4af.
Report an issue: GitHub.