hibernate/hibernate-orm · error · AnnotationException
Class '<componentClassName>' is an '@Embeddable' type and ma
Error message
Class '<componentClassName>' is an '@Embeddable' type and may not be annotated '@BatchSize'
What it means
Thrown by BatchSizeBinder when a class mapped as an @Embeddable is annotated @BatchSize. Hibernate 6.5+ validates annotation placement via dedicated binders, and batch fetching only applies to entity classes and collection roles. An embeddable is always loaded together with its owning entity, so a batch size on it is meaningless and fails metadata binding at SessionFactory build time with an AnnotationException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/binder/internal/BatchSizeBinder.java:33
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Value;
/**
* Binder for the {@link BatchSize} annotation.
*
* @since 6.5
*
* @author Gavin King
*/
public class BatchSizeBinder implements TypeBinder<BatchSize>, AttributeBinder<BatchSize> {
@Override
public void bind(BatchSize batchSize, MetadataBuildingContext context, PersistentClass persistentClass) {
persistentClass.setBatchSize( batchSize.size() );
}
@Override
public void bind(BatchSize batchSize, MetadataBuildingContext context, Component embeddableClass) {
throw new AnnotationException("Class '" + embeddableClass.getComponentClassName()
+ "' is an '@Embeddable' type and may not be annotated '@BatchSize'");
}
@Override
public void bind(BatchSize batchSize, MetadataBuildingContext context, PersistentClass persistentClass, Property property) {
final Value value = property.getValue();
if ( value instanceof Collection collection ) {
collection.setBatchSize( batchSize.size() );
}
else {
throw new AnnotationException("Property '" + property.getName() + "' may not be annotated '@BatchSize'");
}
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Remove @BatchSize from the @Embeddable class.
- To batch-fetch the owning entities, put @BatchSize(size = N) on the owning @Entity class instead.
- If the embeddable declares a lazy collection, put @BatchSize on that collection-typed property (allowed for Collection values).
Example fix
// before
@Embeddable
@BatchSize(size = 10)
public class Address { ... }
// after
@Embeddable
public class Address { ... }
@Entity
@BatchSize(size = 10) // batch-fetch the owning entities
public class User {
@Embedded
private Address address;
} Defensive patterns
Strategy: validation
Validate before calling
for (Class<?> cls : persistentClasses) {
if (cls.isAnnotationPresent(jakarta.persistence.Embeddable.class)
&& cls.isAnnotationPresent(org.hibernate.annotations.BatchSize.class)) {
throw new IllegalStateException("@BatchSize not allowed on @Embeddable " + cls.getName());
}
} Try / catch
Wrap SessionFactory bootstrap (metadata.buildSessionFactory()) in try/catch (org.hibernate.AnnotationException e): the message names the offending class; log it and abort startup. Never catch-and-continue — the metadata is unusable.
Prevention
- Keep @BatchSize on @Entity classes and collection-typed properties only.
- Add a startup mapping lint that scans persistent classes for misplaced Hibernate annotations.
- Treat any AnnotationException during bootstrap as a build failure in CI.
When it happens
Trigger: Registering an @Embeddable class that carries @BatchSize (via MetadataSources.addAnnotatedClass, addPackage, or annotation scanning) and building the SessionFactory. The type-binder overload bind(BatchSize, context, Component) runs and unconditionally throws.
Common situations: Copying @BatchSize onto a shared embeddable (e.g. Address) while refactoring an entity; a leftover annotation after converting an @Entity into an @Embeddable; upgrading to Hibernate 6.5+ where the previously ignored annotation now aborts bootstrap.
Related errors
- Property '<propertyName>' may not be annotated '@BatchSize'
- Class '<componentClassName>' is an '@Embeddable' type and ma
- One to many association '<propertyName>' was annotated '@Col
- Collection '<propertyName>' was annotated '@Collate'
- Root entity '<entityName>' is annotated '@DiscriminatorOptio
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/e50865464e3bd5bd.
Report an issue: GitHub.