{"record":{"id":"a422e6e13e4b2ebe","repo":"hibernate/hibernate-orm","slug":"invalid-entity-graph-definition-s-expected-for","errorCode":null,"errorMessage":"Invalid entity-graph definition '%s'; expected form '${EntityName}( ${property1} ... )'","messagePattern":"Invalid entity-graph definition '(.+?)'; expected form '(.+?)\\( (.+?) \\.\\.\\. \\)'","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java","lineNumber":686,"sourceCode":"\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(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tROOT,\n\t\t\t\t\t\t\t\"Invalid entity-graph definition '%s'; expected form '${EntityName}( ${property1} ... )'\",\n\t\t\t\t\t\t\tgraphString\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tfinal var factory = getSessionFactory();\n\n\t\tfinal String entityName =\n\t\t\t\tfactory.getMappingMetamodel()\n\t\t\t\t\t\t.getImportedName( graphString.substring( 0, separatorPosition ).trim() );\n\t\tfinal String graphNodes = graphString.substring( separatorPosition + 1, terminatorPosition );\n\n\t\tfinal var rootGraph = new RootGraphImpl<>( null, factory.getJpaMetamodel().entity( entityName ) );\n\t\tGraphParser.parseInto( (EntityGraph<?>) rootGraph, graphNodes, getSessionFactory() );\n\t\treturn rootGraph;","sourceCodeStart":668,"sourceCodeEnd":704,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java#L668-L704","documentation":"Thrown by AbstractCommonQueryContract.parseGraph (line 685-692) when an inline entity-graph string has no '(' or no ')' — the parser requires the strict form '${EntityName}( ${property1} ... )' and locates the entity by the text before the first '(' via MappingMetamodel.getImportedName. Note: when parseGraph is invoked through applyEntityGraphHint's string branch, its IllegalArgumentException is caught and rethrown with the broader GraphParser message of error 2361; this exact message surfaces on paths that call/override parseGraph directly.","triggerScenarios":"A fetchgraph hint string like \"Order\" or \"order.items\" (bare name/attribute path, no parentheses and no property list) reaching parseGraph. An unterterminated graph such as \"Order(items\" (missing ')') or \")Order(\" where lastIndexOf(')') is -1. Subclasses or user code calling the protected parseGraph(String) with a malformed string.","commonSituations":"Trying to reference a named graph but forgetting it must exist as @NamedEntityGraph (the inline syntax always needs parentheses); hand-building graph strings from templates; version migrations where older releases tolerated attribute-only strings.","solutions":["Format the string as 'EntityName( attr1, attr2 )' with matching parentheses, e.g. \"Order( items, customer )\"","If you only want a named graph, make sure it is registered under that name via @NamedEntityGraph instead of an inline string","Prefer passing the EntityGraph object or its registered name to avoid string parsing entirely"],"exampleFix":"// before\nquery.setHint( QueryHints.HINT_FETCHGRAPH, \"order.items\" ); // no '(' ')' -> invalid definition\n\n// after\nquery.setHint( QueryHints.HINT_FETCHGRAPH, \"Order( items )\" );","handlingStrategy":"validation","validationCode":"static boolean isInlineGraphForm(String s) {\n    int open = s.indexOf( '(' );\n    int close = s.lastIndexOf( ')' );\n    return open > 0 && close > open; // 'EntityName( attr ... )'\n}\n// use only when isInlineGraphForm(graphString) is true","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build graph strings from one template: ENTITY + \"( \" + String.join(\", \", attrs) + \" )\"","Prefer registered named graphs or EntityGraph objects over hand-built strings","Add a parser round-trip test: session-side parseGraph-compatible strings covered by unit tests"],"tags":["hibernate","entity-graph","graph-parser","parse-error","query-hints"],"backgroundTag":"entity-graph-hint-invalid","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}