{"record":{"id":"3890b3b80f7c27d9","repo":"hibernate/hibernate-orm","slug":"the-string-value-of-the-hint-hintname-must-be","errorCode":null,"errorMessage":"The string value of the hint '{hintName}' must be the name of a named EntityGraph, or a representation understood by GraphParser","messagePattern":"The string value of the hint '(.+?)' must be the name of a named EntityGraph, or a representation understood by GraphParser","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java","lineNumber":668,"sourceCode":"\t\t\tapplyGraph( rootGraphImplementor, graphSemantic );\n\t\t}\n\t\telse if ( value instanceof String string ) {\n\t\t\t// try and interpret it as the name of a @NamedEntityGraph\n\t\t\ttry {\n\t\t\t\tapplyGraph( getSession().getEntityGraph( string ), graphSemantic );\n\t\t\t\t// getEntityGraph throws an exception if not found.  but since we got here, it was found\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcatch (IllegalArgumentException ignore) {\n\t\t\t\t// fall through...\n\t\t\t}\n\n\t\t\t// try and parse it in the entity graph language\n\t\t\ttry {\n\t\t\t\tapplyGraph( parseGraph( string ), graphSemantic );\n\t\t\t}\n\t\t\tcatch ( IllegalArgumentException e ) {\n\t\t\t\tthrow new IllegalArgumentException( \"The string value of the hint '\" + hintName\n\t\t\t\t\t\t\t\t\t\t\t\t\t+ \"' must be the name of a named EntityGraph, or a representation understood by GraphParser\" );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tthrow new IllegalArgumentException( \"The value of the hint '\" + hintName\n\t\t\t\t\t\t\t\t\t\t\t\t+ \"' must be an instance of EntityGraph, the string name of a named EntityGraph, or a string representation understood by GraphParser\" );\n\t\t}\n\t}\n\n\tprotected void applyEnabledFetchProfileHint(String hintName, Object value) {\n\t\tqueryOptions.enableFetchProfile( (String) value );\n\t}\n\n\tprotected RootGraphImplementor<?> parseGraph(String graphString) {\n\t\tfinal int separatorPosition = graphString.indexOf( '(' );\n\t\tfinal int terminatorPosition = graphString.lastIndexOf( ')' );\n\t\tif ( separatorPosition < 0 || terminatorPosition < 0 ) {\n\t\t\tthrow new IllegalArgumentException(","sourceCodeStart":650,"sourceCodeEnd":686,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java#L650-L686","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nquery.setHint( QueryHints.HINT_FETCHGRAPH, \"order-with-itmes\" ); // typo -> IllegalArgumentException\n\n// after\nquery.setHint( QueryHints.HINT_FETCHGRAPH, em.getEntityGraph( \"order-with-items\" ) );\n// or inline form:\nquery.setHint( QueryHints.HINT_FETCHGRAPH, \"Order( items, customer )\" );","handlingStrategy":"validation","validationCode":"if ( value instanceof String name ) {\n    boolean registered = em.getEntityManagerFactory().getNamedEntityGraphs().stream()\n            .anyMatch( holder -> holder.getName().equals( name ) );\n    boolean parseable = name.indexOf( '(' ) >= 0 && name.lastIndexOf( ')' ) >= 0;\n    if ( !registered && !parseable ) throw new IllegalStateException( \"Unknown entity graph: \" + name );\n}\nquery.setHint( QueryHints.HINT_FETCHGRAPH, value );","typeGuard":"static boolean isResolvableGraphHint(Object v, EntityManager em) {\n    if ( v instanceof EntityGraph<?> ) return true;\n    if ( v instanceof String s ) {\n        try { em.getEntityGraph( s ); return true; }\n        catch ( IllegalArgumentException ignore ) { return s.indexOf( '(' ) >= 0 && s.lastIndexOf( ')' ) >= 0; }\n    }\n    return false;\n}","tryCatchPattern":"try {\n    query.setHint( QueryHints.HINT_FETCHGRAPH, graphRef );\n} catch ( IllegalArgumentException e ) {\n    // fall back to no graph (default fetching) instead of failing the request\n    log.warn( \"Unresolvable entity graph '{}', continuing without graph\", graphRef );\n}","preventionTips":["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()"],"tags":["hibernate","entity-graph","fetchgraph","loadgraph","query-hints","graph-parser"],"backgroundTag":"entity-graph-hint-invalid","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}