hibernate/hibernate-orm · error · IllegalArgumentException
The string value of the hint '{hintName}' must be the name o
Error message
The string value of the hint '{hintName}' must be the name of a named EntityGraph, or a representation understood by GraphParser What it means
Thrown when a fetchgraph/loadgraph hint ('jakarta.persistence.fetchgraph' or 'jakarta.persistence.loadgraph') receives a String value that is neither the name of a registered @NamedEntityGraph nor a string Hibernate's GraphParser understands. AbstractCommonQueryContract.applyEntityGraphHint (line ~654) first tries session.getEntityGraph(string); if that lookup fails it calls parseGraph(string) inside a try, and any IllegalArgumentException from either step is rethrown with this combined message at line 668.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java:668
applyGraph( rootGraphImplementor, graphSemantic );
}
else if ( value instanceof String string ) {
// try and interpret it as the name of a @NamedEntityGraph
try {
applyGraph( getSession().getEntityGraph( string ), graphSemantic );
// getEntityGraph throws an exception if not found. but since we got here, it was found
return;
}
catch (IllegalArgumentException ignore) {
// fall through...
}
// try and parse it in the entity graph language
try {
applyGraph( parseGraph( string ), graphSemantic );
}
catch ( IllegalArgumentException e ) {
throw new IllegalArgumentException( "The string value of the hint '" + hintName
+ "' must be the name of a named EntityGraph, or a representation understood by GraphParser" );
}
}
else {
throw new IllegalArgumentException( "The value of the hint '" + hintName
+ "' must be an instance of EntityGraph, the string name of a named EntityGraph, or a string representation understood by GraphParser" );
}
}
protected void applyEnabledFetchProfileHint(String hintName, Object value) {
queryOptions.enableFetchProfile( (String) value );
}
protected RootGraphImplementor<?> parseGraph(String graphString) {
final int separatorPosition = graphString.indexOf( '(' );
final int terminatorPosition = graphString.lastIndexOf( ')' );
if ( separatorPosition < 0 || terminatorPosition < 0 ) {
throw new IllegalArgumentException(View on GitHub (pinned to fad1729dce)
Solutions
- Fix the name to match the @NamedEntityGraph name exactly, or register the graph first: em.createEntityGraph / @NamedEntityGraph on the entity
- If you meant an inline graph, use the exact form 'EntityName( attribute1, attribute2 )' with the entity's Hibernate name (imported name) and real attribute names
- Prefer passing the EntityGraph object itself: query.setHint(HINT_FETCHGRAPH, em.getEntityGraph("orderGraph")) — this bypasses both lookup and parsing
- List available graph names via session.getFactory().getNamedEntityGraphs().keySet() to verify what is registered
Example fix
// before query.setHint( QueryHints.HINT_FETCHGRAPH, "order-with-itmes" ); // typo -> IllegalArgumentException // after query.setHint( QueryHints.HINT_FETCHGRAPH, em.getEntityGraph( "order-with-items" ) ); // or inline form: query.setHint( QueryHints.HINT_FETCHGRAPH, "Order( items, customer )" );
Defensive patterns
Strategy: validation
Validate before calling
if ( value instanceof String name ) {
boolean registered = em.getEntityManagerFactory().getNamedEntityGraphs().stream()
.anyMatch( holder -> holder.getName().equals( name ) );
boolean parseable = name.indexOf( '(' ) >= 0 && name.lastIndexOf( ')' ) >= 0;
if ( !registered && !parseable ) throw new IllegalStateException( "Unknown entity graph: " + name );
}
query.setHint( QueryHints.HINT_FETCHGRAPH, value ); Type guard
static boolean isResolvableGraphHint(Object v, EntityManager em) {
if ( v instanceof EntityGraph<?> ) return true;
if ( v instanceof String s ) {
try { em.getEntityGraph( s ); return true; }
catch ( IllegalArgumentException ignore ) { return s.indexOf( '(' ) >= 0 && s.lastIndexOf( ')' ) >= 0; }
}
return false;
} Try / catch
try {
query.setHint( QueryHints.HINT_FETCHGRAPH, graphRef );
} catch ( IllegalArgumentException e ) {
// fall back to no graph (default fetching) instead of failing the request
log.warn( "Unresolvable entity graph '{}', continuing without graph", graphRef );
} Prevention
- Reference graph names via constants declared next to @NamedEntityGraph
- Prefer passing the EntityGraph object from em.getEntityGraph(name) over strings
- At startup, assert every graph name your code uses exists in factory.getNamedEntityGraphs()
When it happens
Trigger: query.setHint("jakarta.persistence.fetchgraph", "orderGrapf") where the @NamedEntityGraph is actually named "orderGraph" (typo). Passing a graph string that is not parseable, e.g. "order.items" without parentheses, "Order( nonExistentAttr )" with an unknown attribute, or an entity prefix that is not a known/imported entity name so factory.getMappingMetamodel().getImportedName fails.
Common situations: Typos in named-graph names; assuming JPQL join paths or JPA attribute names work as inline graph strings; graph defined in a different persistence unit or registered via a different SessionFactory; migrating code that used the legacy javax.persistence.fetchgraph key whose handling now flows through the same parser; entity mapped under an entity name (@Entity(name=...)) so the class name prefix doesn't resolve.
Related errors
- Invalid entity-graph definition '%s'; expected form '${Entit
- The value of the hint '{hintName}' must be an instance of En
- Unrecognized graph_parser_mode value : " + graphParserMode +
- Duplicate named entity graph '%s'
- The 'root' parameter of the @NamedEntityGraph should be pass
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/3890b3b80f7c27d9.
Report an issue: GitHub.