{"record":{"id":"b8983811475d237f","repo":"hibernate/hibernate-orm","slug":"named-native-query-s-did-not-specify-query-stri","errorCode":null,"errorMessage":"Named native query [%s] did not specify query string","messagePattern":"Named native query \\[(.+?)\\] did not specify query string","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/NamedQueryBinder.java","lineNumber":135,"sourceCode":"\n\t\tfinal var implicitResultSetMappingBuilder =\n\t\t\t\tnew ImplicitHbmResultSetMappingDescriptorBuilder( registrationName, context );\n\n\t\tboolean foundQuery = false;\n\t\tfor ( Object content : namedQueryBinding.getContent() ) {\n\t\t\tfinal boolean wasQuery = processNamedQueryContentItem(\n\t\t\t\t\tcontent,\n\t\t\t\t\tbuilder,\n\t\t\t\t\timplicitResultSetMappingBuilder,\n\t\t\t\t\tnamedQueryBinding,\n\t\t\t\t\tcontext\n\t\t\t);\n\t\t\tif ( wasQuery ) {\n\t\t\t\tfoundQuery = true;\n\t\t\t}\n\t\t}\n\t\tif ( !foundQuery ) {\n\t\t\tthrow new MappingException(\n\t\t\t\t\t\"Named native query [%s] did not specify query string\"\n\t\t\t\t\t\t\t.formatted( namedQueryBinding.getName() ),\n\t\t\t\t\tcontext.getOrigin()\n\t\t\t);\n\t\t}\n\n\t\tfinal var collector = context.getMetadataCollector();\n\n\t\tif ( implicitResultSetMappingBuilder.hasAnyReturns() ) {\n\t\t\tif ( isNotEmpty( namedQueryBinding.getResultsetRef() ) ) {\n\t\t\t\tthrow new MappingException(\n\t\t\t\t\t\t\"Named native query [%s] specified both a resultset-ref and an inline mapping of results\"\n\t\t\t\t\t\t\t\t.formatted( namedQueryBinding.getName() ),\n\t\t\t\t\t\tcontext.getOrigin()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcollector.addResultSetMapping( implicitResultSetMappingBuilder.build( context ) );","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/NamedQueryBinder.java#L117-L153","documentation":"The native-SQL counterpart of the HQL check: a <sql-query name='...'> must include the SQL text as one of its content items. The walker sets foundQuery only when processNamedQueryContentItem actually consumed the query string; if the element holds only <return>/<return-join>/resultset-ref/ synchronization elements and no SQL text, this MappingException is thrown. The same binder then also rejects combining resultset-ref with inline returns, underlining that returns complement - never replace - the SQL body.","triggerScenarios":"<sql-query name='x'><return alias='u' class='User'/></sql-query> with no actual SQL text; SQL moved out to an external file leaving an empty element; CDATA-wrapped SQL dropped during migration.","commonSituations":"Refactoring native queries into code or repositories and leaving stubs in the mapping; copy-pasting result-mapping-only templates; editing tools that strip CDATA bodies.","solutions":["Add the SQL text as the <sql-query> element's content (CDATA is fine)","Verify <return>/<return-join>/resultset-ref are accompanied by the SQL body, not used instead of it","Add a build-time check that every <sql-query> element has non-blank text content"],"exampleFix":"// before\n<sql-query name='findUsers'>\n    <return alias='u' class='User'/>\n</sql-query>\n\n// after\n<sql-query name='findUsers'>\n    <return alias='u' class='User'/>\n    <![CDATA[SELECT {u.*} FROM users u WHERE u.status = 'A']]>\n</sql-query>","handlingStrategy":"validation","validationCode":"NodeList sqlQueries = doc.getElementsByTagName(\"sql-query\");\nfor (int i = 0; i < sqlQueries.getLength(); i++) {\n    Element q = (Element) sqlQueries.item(i);\n    boolean hasSql = q.getTextContent() != null && !q.getTextContent().isBlank();\n    if (!hasSql) {\n        throw new IllegalStateException(\"named native query '\" + q.getAttribute(\"name\") + \"' has no SQL text\");\n    }\n}","typeGuard":null,"tryCatchPattern":"catch (MappingException e) at bootstrap; the message names the empty native query. Add the SQL body (CDATA is fine) alongside any <return> declarations and rebuild.","preventionTips":["Treat <return>/<return-join> as complements to the SQL body, never replacements","Add a CI lint that every <sql-query> has non-blank text content","Prefer CDATA-wrapped SQL to survive XML edits and tooling"],"tags":["hibernate","hbm-mapping","named-native-query","sql","empty-query"],"backgroundTag":"empty-named-query","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}