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
- Set a unique non-blank name on the @NamedStatement annotation.
- Keep statement names in constants and test they are non-blank before release.
- 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
- Treat @NamedStatement like named queries: constant-backed unique names.
- Add a reflection scan over annotated classes asserting non-blank names in CI.
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
- Class or package level '@NamedQuery' annotation must specify
- Class or package level '@NamedNativeQuery' annotation must s
- Class or package level '@NamedStoredProcedureQuery' annotati
- Identifier property '" + getPath( holder, data ) + "' cannot
- Could not locate attribute member - %s (%s)
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/cf3745f2f4a81e71.
Report an issue: GitHub.