hibernate/hibernate-orm · error · InvalidNamedEntityGraphParameterException

The 'root' parameter of the @NamedEntityGraph should be pass

Error message

The 'root' parameter of the @NamedEntityGraph should be passed. Graph : ${name}

What it means

Hibernate throws this while building metadata when a @NamedEntityGraph declaration carries no resolvable root entity type. The parser only needs the annotation's 'root' attribute when the graph is not attached to a known entity class (e.g. declared in XML, on a package, or processed without an owning entity); if 'root' is left at its default void.class in that situation, the graph cannot be bound to any entity and bootstrap fails with InvalidNamedEntityGraphParameterException.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/NamedGraphCreatorParsed.java:136

		else {
			entityDomainType = resolveEntityDomainTypeFromAnnotation( entityDomainClassResolver );
		}


		final String graphName = this.name == null ? entityDomainType.getName() : this.name;

		return GraphParsing.visit( graphName, entityDomainType, graphContext.attributeList(),
				entityName -> resolve( entityName, entityDomainNameResolver ) );
	}


	private <T> EntityDomainType<T> resolveEntityDomainTypeFromAnnotation(GraphParserEntityClassResolver entityDomainClassResolver) {
		final Class<?> annotationRootAttribute = annotation.root();
		final boolean isAnnotationRootAttributeVoid = void.class.equals( annotationRootAttribute );

		if ( entityType == null ) {
			if ( isAnnotationRootAttributeVoid ) {
				throw new InvalidNamedEntityGraphParameterException(
						"The 'root' parameter of the @NamedEntityGraph should be passed. Graph : " + annotation.name()
				);
			}

			//noinspection unchecked
			return (EntityDomainType<T>) entityDomainClassResolver.resolveEntityClass( annotationRootAttribute );
		}

		if ( !isAnnotationRootAttributeVoid ) {
			if ( !annotationRootAttribute.equals( entityType ) ) {
				throw new InvalidNamedEntityGraphParameterException(
						"The 'root' parameter of the @NamedEntityGraph annotation must reference the entity '"
						+ entityType.getName()
						+ "', but '" + annotationRootAttribute.getName() + "' was provided."
						+ " Graph :" + annotation.name()
				);
			}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add root = YourEntity.class to the @NamedEntityGraph (or the corresponding root element in orm.xml).
  2. Move the @NamedEntityGraph annotation directly onto the entity class it applies to, where the owner supplies the root implicitly.
  3. In orm.xml, nest the <named-entity-graph> inside the <entity> element instead of declaring it at the mapping-file root.

Example fix

// before (orm.xml or package-level declaration, no entity context)
@NamedEntityGraph(name = "order.withLines")

// after
@NamedEntityGraph(name = "order.withLines", root = Order.class)
// or: put the annotation on the Order entity class itself
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast before SessionFactory build: every graph without an owning entity needs a root
for (var pkg : Package.getPackages()) {
    var graphs = pkg.isAnnotationPresent(NamedEntityGraphs.class)
            ? pkg.getAnnotation(NamedEntityGraphs.class).value()
            : new NamedEntityGraph[0];
    for (var g : graphs) {
        if (void.class.equals(g.root())) {
            throw new IllegalStateException("@NamedEntityGraph '" + g.name() + "' outside an entity must set root=");
        }
    }
}

Try / catch

try {
    Metadata metadata = metadataSources.buildMetadata();
} catch (InvalidNamedEntityGraphParameterException e) {
    throw new IllegalStateException("Entity graph misconfigured: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Declaring @NamedEntityGraph (or a <named-entity-graph> in orm.xml) without a 'root' element/attribute in a location where no entity type is supplied: orm.xml graphs not nested inside an <entity>, package-level declarations, or programmatic/annotation processing paths where entityType is null and annotation.root() == void.class.

Common situations: Migrating entity graphs from annotations to orm.xml (or vice versa) and forgetting the root; declaring shared graphs in package-info.java; splitting graph definitions out of the entity class during refactoring; upgrading Hibernate versions where previously-lenient parsing now enforces the root.

Related errors


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