hibernate/hibernate-orm · error · AnnotationException

Class or package level '@NamedStatement' annotation must spe

Error message

Class or package level '@NamedStatement' annotation must specify a 'name'

What it means

QueryBinder.bindStatement registers a Hibernate-specific @NamedStatement (an HQL INSERT/UPDATE/DELETE 'mutation' statement); if annotation.name() is blank, bootstrap throws AnnotationException. Like named queries, named statements need a non-empty registration key.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/QueryBinder.java:126

			final var definition = NamedHqlSelectionDefinitionImpl.from( namedQuery, annotationTarget );
			final var collector = context.getMetadataCollector();
			if ( isDefault ) {
				collector.addDefaultQuery( definition );
			}
			else {
				collector.addNamedQuery( definition );
			}
		}
	}

	public static void bindStatement(
			NamedStatement annotation,
			MetadataBuildingContext context,
			AnnotationTarget location) {
		if ( annotation != null ) {
			final String registrationName = annotation.name();
			if ( registrationName.isBlank() ) {
				throw new AnnotationException(
						"Class or package level '@NamedStatement' annotation must specify a 'name'" );
			}

			if ( BOOT_LOGGER.isTraceEnabled() ) {
				BOOT_LOGGER.bindingNamedMutation( registrationName,
						annotation.statement().replace( '\n', ' ' ) );
			}

			final var definition = NamedHqlMutationDefinitionImpl.from( annotation, location );
			context.getMetadataCollector().addNamedQuery( definition );
		}
	}

	public static void bindNativeStatement(
			NamedNativeStatement annotation,
			MetadataBuildingContext context,
			AnnotationTarget location) {
		if ( annotation != null ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Set a unique non-blank name on the @NamedStatement annotation.
  2. Keep statement names in constants and test they are non-blank before release.
  3. If names are generated, fix the generator to always emit a key.

Example fix

// before
@NamedStatement(name = "", statement = "update Person p set p.active = true")

// after
@NamedStatement(name = "Person.activateAll", statement = "update Person p set p.active = true")
Defensive patterns

Strategy: validation

Validate before calling

@Test void namedStatementsHaveNames() {
    NamedStatement s = Order.class.getAnnotation(NamedStatement.class);
    if (s != null) assertTrue(!s.name().isBlank(), "@NamedStatement needs a name");
}

Try / catch

try {
    metadata = sources.buildMetadata();
} catch (AnnotationException e) {
    failBuild("Named statement registration failed: " + e.getMessage());
}

Prevention

When it happens

Trigger: @NamedStatement(name = "", statement = "update Person p set p.active = true") declared on an entity or package and processed during annotation binding. Blank means empty or whitespace-only.

Common situations: Adopting Hibernate 6.2+ @NamedStatement and copying @NamedQuery examples with the wrong member names; leaving name empty while iterating on the statement text; generated or externalized statement catalogs missing the key.

Related errors


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