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

  1. Put the HQL text inside the <query> element: <query name='usersByName'>from User u where u.name = :name</query>
  2. If the body uses CDATA, verify the CDATA section survived editing
  3. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/14c046c8e434a9f7. Report an issue: GitHub.