hibernate/hibernate-orm · error · MappingException
Named query [%s] did not specify query string
Error message
Named query [%s] did not specify query string
What it means
A named HQL query (<query name='...'>...</query> in hbm.xml) must contain the query text, either as the element's text content or via recognized content items. The binder tracks foundQuery while walking the element's content; if nothing it processed was the query text (element empty, whitespace-only, or containing only query-param/hint elements), it throws this MappingException when adding the named query.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/NamedQueryBinder.java:77
for ( Object content : namedQueryBinding.getContent() ) {
if ( content instanceof String string ) {
if ( isNotBlank( string ) ) {
queryBuilder.setHqlString( string.trim() );
foundQuery = true;
}
}
else if ( content instanceof JAXBElement<?> element
&& element.getValue() instanceof JaxbHbmQueryParamType queryParamType ) {
queryBuilder.addParameterTypeHint( queryParamType.getName(), queryParamType.getType() );
}
else {
throw new AssertionFailure( "Unexpected content type: " + content.getClass().getName() );
}
}
if ( !foundQuery ) {
throw new MappingException(
"Named query [%s] did not specify query string"
.formatted( namedQueryBinding.getName() ),
context.getOrigin()
);
}
context.getMetadataCollector().addNamedQuery( queryBuilder.build() );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named native query
public static void processNamedNativeQuery(
HbmLocalMetadataBuildingContext context,
JaxbHbmNamedNativeQueryType namedQueryBinding) {
processNamedNativeQuery( context, namedQueryBinding, "" );
}View on GitHub (pinned to fad1729dce)
Solutions
- Put the HQL text inside the <query> element: <query name='usersByName'>from User u where u.name = :name</query>
- If the body uses CDATA, verify the CDATA section survived editing
- Add a build-time check that every <query> element has non-blank text content
Example fix
// before <query name='usersByName'/> // after <query name='usersByName'><![CDATA[from User u where u.name = :name]]></query>
Defensive patterns
Strategy: validation
Validate before calling
NodeList queries = doc.getElementsByTagName("query");
for (int i = 0; i < queries.getLength(); i++) {
Element q = (Element) queries.item(i);
boolean hasText = q.getTextContent() != null && !q.getTextContent().isBlank();
if (!hasText) {
throw new IllegalStateException("named query '" + q.getAttribute("name") + "' has no query text");
}
} Try / catch
catch (MappingException e) at bootstrap; the message names the empty named query. Fill in its HQL body (CDATA is fine) and rebuild.
Prevention
- Externalize HQL to annotations or a dedicated file with a lint step rather than inline stubs
- Assert every <query> element has non-blank text in CI
- Avoid commenting out query bodies instead of removing the element
When it happens
Trigger: <query name='usersByName'/> with no body; the HQL was externalized or commented out leaving the element empty; CDATA mangled during file edits so the text node is lost.
Common situations: Editing mapping files and accidentally emptying the query body; templating or generation steps leaving placeholder queries empty; migration tooling dropping CDATA sections.
Related errors
- Named native query [%s] did not specify query string
- Insert conflict 'do update' clause with constraint name is n
- field type not supported on Derby: " + unit
- format() function not supported on Derby
- field type not supported on Derby: " + unit
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/14c046c8e434a9f7.
Report an issue: GitHub.