hibernate/hibernate-orm · error · NoSuchElementException

No node for attribute

Error message

No node for attribute: {}

What it means

GraphImpl.getAttributeNode(String) throws NoSuchElementException('No node for attribute: ...') when the name resolves to a real attribute of the graphed type (including inherited ones) but this graph holds no node for it — nothing was ever added via addAttributeNode, or the node was removed. It signals an absent node, not an unknown attribute (that case throws IllegalArgumentException).

Solutions

  1. Create the node instead of assuming it exists: addAttributeNode(name) returns the existing or newly created node
  2. Check presence via getAttributeNodes() names (or hasAttributeNode after validating the name) before fetching
  3. When inspecting graphs you did not build, treat a missing node as 'attribute not fetched' rather than an error

Example fix

// before
var node = graph.getAttributeNode("customer"); // graph never added it → NoSuchElementException

// after — addAttributeNode returns the existing or newly created node
var node = graph.addAttributeNode("customer");
Defensive patterns

Strategy: validation

Validate before calling

// Check node presence without exceptions before getAttributeNode(name)
static Optional<jakarta.persistence.AttributeNode<?>> nodeFor(EntityGraph<?> graph, String attrName) {
    return graph.getAttributeNodes().stream()
            .filter(n -> n.getAttributeName().equals(attrName))
            .findFirst();
}

Prevention

When it happens

Trigger: Calling getAttributeNode(name) on a freshly created empty graph (nodes only exist after addAttributeNode), after the node was removed, or when inspecting a graph parsed from a string or loaded by name that never mentioned the attribute.

Common situations: Graph merge/inspection utilities assuming nodes exist for all attributes; reading named/parsed graphs for attributes that were never included; interleaving removal and lookup logic.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/23c0cbf76eeb03c7. Report an issue: GitHub.

Appendix: source

Thrown at hibernate-core/src/main/java/org/hibernate/graph/internal/GraphImpl.java:116

			&& attributeNodes.containsKey( attribute );
	}

	@Override
	public boolean hasAttributeNode(@Nonnull Attribute<? super J, ?> attribute) {
		return attributeNodes != null
			&& attributeNodes.containsKey( (PersistentAttribute<? super J, ?>) attribute );
	}

	@Override
	@Nonnull
	public <Y> AttributeNodeImplementor<Y,?,?> getAttributeNode(@Nonnull String attributeName) {
		final var attribute = findAttributeInSupertypes( attributeName );
		if ( attribute == null ) {
			throw new IllegalArgumentException( "Unknown attribute: " + attributeName );
		}
		final var node = attributeNodes == null ? null : attributeNodes.get( attribute );
		if ( node == null ) {
			throw new NoSuchElementException( "No node for attribute: " + attributeName );
		}
		@SuppressWarnings("unchecked") // The JPA API is unsafe by nature
		final var castNode = (AttributeNodeImplementor<Y, ?, ?>) node;
		return castNode;
	}

	@Override
	@Nonnull
	public <Y> AttributeNodeImplementor<Y,?,?> getAttributeNode(@Nonnull Attribute<? super J, Y> attribute) {
		final var node = attributeNodes == null ? null
				: attributeNodes.get( (PersistentAttribute<? super J, ?>) attribute );
		if ( node == null ) {
			throw new NoSuchElementException( "No node for attribute: " + attribute );
		}
		@SuppressWarnings("unchecked")
		final var castNode = (AttributeNodeImplementor<Y, ?, ?>) node;
		return castNode;
	}

View on GitHub (pinned to fad1729dce)