{"record":{"id":"66e7c1c489cb877c","repo":"hibernate/hibernate-orm","slug":"hbm-return-join-resultset-mapping-must-be-used-in","errorCode":null,"errorMessage":"HBM return-join ResultSet mapping must be used in conjunction with root entity or collection return : \" + registrationName","messagePattern":"HBM return-join ResultSet mapping must be used in conjunction with root entity or collection return : \" \\+ registrationName","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/query/ImplicitHbmResultSetMappingDescriptorBuilder.java","lineNumber":152,"sourceCode":"\t\tif ( fetchParentByAlias == null ) {\n\t\t\tfetchParentByAlias = new HashMap<>();\n\t\t}\n\t\tfetchParentByAlias.put( returnMapping.getAlias(), resultDescriptor );\n\n\t\treturn this;\n\t}\n\n\tpublic HbmResultSetMappingDescriptor build(HbmLocalMetadataBuildingContext context) {\n\t\tif ( foundCollectionReturn && resultDescriptors.size() > 1 ) {\n\t\t\tthrow new MappingException(\n\t\t\t\t\t\"HBM return-collection ResultSet mapping cannot define entity or scalar returns : \" + registrationName,\n\t\t\t\t\tcontext.getOrigin()\n\t\t\t);\n\t\t}\n\n\t\tif ( joinDescriptors != null ) {\n\t\t\tif ( ! foundEntityReturn && ! foundCollectionReturn ) {\n\t\t\t\tthrow new MappingException(\n\t\t\t\t\t\t\"HBM return-join ResultSet mapping must be used in conjunction with root entity or collection return : \" + registrationName,\n\t\t\t\t\t\tcontext.getOrigin()\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn new HbmResultSetMappingDescriptor(\n\t\t\t\tregistrationName,\n\t\t\t\tresultDescriptors,\n\t\t\t\tjoinDescriptors != null\n\t\t\t\t\t\t? joinDescriptors\n\t\t\t\t\t\t: Collections.emptyMap(),\n\t\t\t\tfetchParentByAlias != null\n\t\t\t\t\t\t? fetchParentByAlias\n\t\t\t\t\t\t: Collections.emptyMap()\n\t\t);\n\t}\n}","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/query/ImplicitHbmResultSetMappingDescriptorBuilder.java#L134-L170","documentation":"The implicit result set mapping builder treats joinDescriptors != null as 'this query has <return-join/> entries'. build() then requires at least one root return — foundEntityReturn or foundCollectionReturn — to attach the joins to. With joins present but neither root return found, this MappingException is thrown: a join fetch cannot be the only return of a native query.","triggerScenarios":"A <sql-query> containing only one or more <return-join property=\"o.items\"/> elements with no <return/> or <return-collection/>; a root return accidentally deleted or commented out while the joins remained.","commonSituations":"Editing long native query mappings and dropping the root return; copy-pasting a join block into a new query skeleton that never got its root return; migrations where the root return element was renamed.","solutions":["Add a root <return alias=\"o\" entity-name=\"...\"/> (or <return-collection/>) whose alias matches the owner aliases used in the joins.","Make sure the root return is a direct child of <sql-query>, not nested inside another element where the builder would not count it."],"exampleFix":"<!-- before: only a join, no root return -->\n<sql-query name=\"q\">\n    <return-join alias=\"i\" property=\"o.items\"/>\n</sql-query>\n\n<!-- after -->\n<sql-query name=\"q\">\n    <return alias=\"o\" entity-name=\"com.acme.Order\"/>\n    <return-join alias=\"i\" property=\"o.items\"/>\n</sql-query>","handlingStrategy":"validation","validationCode":"boolean hasRootReturn = queryElement.element( \"return\" ) != null\n        || queryElement.element( \"return-collection\" ) != null;\nboolean hasJoins = !queryElement.elements( \"return-join\" ).isEmpty();\nif ( hasJoins && !hasRootReturn ) {\n    throw new IllegalStateException( \"return-join requires a root return in query \" + queryName );\n}","typeGuard":null,"tryCatchPattern":"catch ( MappingException e ) {\n    if ( e.getMessage().startsWith( \"HBM return-join ResultSet mapping must be used in conjunction\" ) ) {\n        // e.getOrigin() names the file; add the missing <return> or <return-collection> root\n    }\n}","preventionTips":["Structure native query mappings as: one root return, then joins referencing its alias.","When trimming query returns, remove dependent joins together with the root return."],"tags":["hibernate","hbm-xml","native-query","return-join","result-set-mapping"],"backgroundTag":"orphan-join-mapping","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}