{"record":{"id":"348946f3c46313b1","repo":"hibernate/hibernate-orm","slug":"passed-properties-contained-both-a-load-and-a-fetc","errorCode":null,"errorMessage":"Passed properties contained both a LOAD and a FETCH graph which is illegal - only one should be passed","messagePattern":"Passed properties contained both a LOAD and a FETCH graph which is illegal - only one should be passed","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/engine/spi/EffectiveEntityGraph.java","lineNumber":126,"sourceCode":"\t *\n\t * @throws IllegalArgumentException If both kinds of graphs were present in the properties/hints\n\t * @throws IllegalStateException If previous state is still available (hasn't been cleared).\n\t */\n\tpublic void applyConfiguredGraph(@Nullable Map<String,?> properties) {\n\t\tif ( properties != null && !properties.isEmpty() ) {\n\t\t\tvar fetchHint = (RootGraphImplementor<?>) properties.get( HINT_JAVAEE_FETCH_GRAPH );\n\t\t\tvar loadHint = (RootGraphImplementor<?>) properties.get( HINT_JAVAEE_LOAD_GRAPH );\n\t\t\tif ( fetchHint == null ) {\n\t\t\t\tfetchHint = (RootGraphImplementor<?>) properties.get( HINT_SPEC_FETCH_GRAPH );\n\t\t\t}\n\t\t\tif ( loadHint == null ) {\n\t\t\t\tloadHint = (RootGraphImplementor<?>) properties.get( HINT_SPEC_LOAD_GRAPH );\n\t\t\t}\n\n\t\t\tif ( fetchHint != null ) {\n\t\t\t\tif ( loadHint != null ) {\n\t\t\t\t\t// can't have both\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\"Passed properties contained both a LOAD and a FETCH graph which is illegal - \" +\n\t\t\t\t\t\t\t\"only one should be passed\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tapplyGraph( fetchHint, GraphSemantic.FETCH );\n\t\t\t}\n\t\t\telse if ( loadHint != null ) {\n\t\t\t\tapplyGraph( loadHint, GraphSemantic.LOAD );\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic void clear() {\n\t\tsemantic = null;\n\t\tgraph = null;\n\t}\n\n\tpublic void withAppliedGraph(GraphSemantic semantic, RootGraphImplementor<?> graph, Runnable action) {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/engine/spi/EffectiveEntityGraph.java#L108-L144","documentation":"EffectiveEntityGraph.applyConfiguredGraph() inspects a properties/hints map for the four graph hint keys (javax/jakarta persistence fetchgraph and loadgraph). A fetch graph and a load graph apply contradictory semantics to the same operation, so supplying both is rejected with IllegalArgumentException.","triggerScenarios":"Passing a properties map that contains both HINT_SPEC/JAVAEE_FETCH_GRAPH and HINT_SPEC/JAVAEE_LOAD_GRAPH (any mix of 'jakarta.persistence.fetchgraph', 'jakarta.persistence.loadgraph', 'javax.persistence.fetchgraph', 'javax.persistence.loadgraph') to an API that feeds applyConfiguredGraph(), such as EntityManager.find(cls, id, hints), session find-by-key operations, or Query hint processing.","commonSituations":"Hint maps assembled by merging defaults with per-call overrides (framework or utility code) without removing the losing key; javax-to-jakarta migration where both spellings get added; Spring Data JPA @EntityGraph combined with manually put graph hints; copy-pasting hint constants between call sites.","solutions":["Remove one of the two hints so the map contains only a fetchgraph or only a loadgraph","Sanitize merged hint maps before use: strip the unused key after merging","Standardize on one spelling (jakarta.persistence.*) and audit shared hint maps for stray javax keys"],"exampleFix":"// before\nMap<String, Object> hints = new HashMap<>();\nhints.put(\"jakarta.persistence.fetchgraph\", fetchGraph);\nhints.put(\"jakarta.persistence.loadgraph\", loadGraph); // both present -> IllegalArgumentException\nem.find(Order.class, id, hints);\n\n// after\nMap<String, Object> hints = new HashMap<>();\nhints.put(\"jakarta.persistence.fetchgraph\", fetchGraph);\nem.find(Order.class, id, hints);","handlingStrategy":"validation","validationCode":"private static final Set<String> GRAPH_HINT_KEYS = Set.of(\n    \"jakarta.persistence.fetchgraph\", \"jakarta.persistence.loadgraph\",\n    \"javax.persistence.fetchgraph\", \"javax.persistence.loadgraph\");\n\nstatic void assertSingleGraphHint(Map<String, Object> hints) {\n    List<String> present = GRAPH_HINT_KEYS.stream()\n        .filter(hints::containsKey).toList();\n    if (present.size() > 1) {\n        throw new IllegalArgumentException(\"Pass only one entity-graph hint, found: \" + present);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    em.find(Order.class, id, hints);\n} catch (IllegalArgumentException e) {\n    if (String.valueOf(e.getMessage()).contains(\"both a LOAD and a FETCH graph\")) {\n        hints.remove(\"jakarta.persistence.loadgraph\"); // keep fetchgraph only\n        em.find(Order.class, id, hints);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Centralize hint-map construction in one helper so both keys can never be added","When merging hint maps, remove graph-hint keys from the loser before merging","Pick one family (jakarta.* or javax.*) and forbid the other via a build-time check"],"tags":["hibernate","jpa-hints","entity-graph","illegal-argument","fetch-vs-load"],"backgroundTag":"conflicting-jpa-hints","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}