hibernate/hibernate-orm · error · AnnotationException
Error processing @TypeBinderType annotation '%s' for entity
Error message
Error processing @TypeBinderType annotation '%s' for entity type '%s'
What it means
Hibernate throws this AnnotationException while binding an entity class when a custom binder registered through @TypeBinderType fails. The exception only wraps the real failure: the original exception thrown inside your TypeBinder.bind() implementation is attached as the cause. Diagnose the cause, not the wrapper message.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/Binders.java:52
}
catch (Exception e) {
throw new AnnotationException(
"Error processing @TypeBinderType annotation '%s' for embeddable type '%s'"
.formatted( annotation, embeddable.getComponentClassName() ), e );
}
}
static <A extends Annotation> void callTypeBinder(
Annotation annotation, Class<A> annotationType,
PersistentClass entity,
MetadataBuildingContext context) {
try {
typeBinder( annotationType )
.bind( annotationType.cast( annotation ),
context, entity );
}
catch (Exception e) {
throw new AnnotationException(
"Error processing @TypeBinderType annotation '%s' for entity type '%s'"
.formatted( annotation, entity.getClassName() ), e );
}
}
static <A extends Annotation> void callPropertyBinder(
Annotation annotation, Class<A> annotationType,
PersistentClass entity, Property property,
MetadataBuildingContext context) {
try {
propertyBinder( annotationType )
.bind( annotationType.cast( annotation ),
context, entity, property );
}
catch (Exception e) {
throw new AnnotationException(
"error processing @AttributeBinderType annotation '%s' for attribute '%s' of entity type '%s'"
.formatted( annotation, property.getName(), entity.getClassName() ), e );View on GitHub (pinned to fad1729dce)
Solutions
- Inspect the exception cause chain (getCause()) - the real failure is inside your TypeBinder.bind() implementation
- Reproduce with a minimal Metadata build in a test and step into the binder
- Validate assumptions (column exists, property present, targetEntity set) inside the binder and throw precise IllegalArgumentException messages
- Give the binder class a public no-arg constructor and matching generic type argument
Example fix
// before
public class AuditBinder implements TypeBinder<Audited> {
public void bind(Audited ann, MetadataBuildingContext ctx, PersistentClass entity) {
entity.getTable().getColumn( ann.column() ).setNullable( false ); // throws if column absent
}
}
// after
public class AuditBinder implements TypeBinder<Audited> {
public void bind(Audited ann, MetadataBuildingContext ctx, PersistentClass entity) {
Column col = entity.getTable().getColumn( ann.column() );
if ( col == null ) {
throw new IllegalArgumentException( "Entity " + entity.getClassName()
+ " has no column " + ann.column() + " for @Audited" );
}
col.setNullable( false );
}
} Defensive patterns
Strategy: try-catch
Try / catch
try {
SessionFactory sf = metadata.getSessionFactoryBuilder().build();
}
catch ( AnnotationException e ) {
Throwable cause = e.getCause() != null ? e.getCause() : e;
throw new IllegalStateException( "Custom binder failed for entity during bootstrap: "
+ cause.getMessage(), cause );
} Prevention
- Boot the SessionFactory in a CI test for every entity using custom binder annotations
- Resolve metadata (columns, properties) defensively inside binders and throw precise messages when absent
- Keep binders free of environment dependencies - they run at bootstrap, not per request
- Check the binder's public no-arg constructor and generic type argument in a unit test
When it happens
Trigger: A user-defined annotation meta-annotated with @TypeBinderType is placed on an @Entity or @MappedSuperclass class. During metadata building Binders.callTypeBinder(Annotation, Class<A>, PersistentClass, MetadataBuildingContext) instantiates the binder and calls bind(annotation, context, entity); any exception from bind() or binder instantiation is caught and rethrown wrapped in this message.
Common situations: A binder looks up a table column or property that does not exist on the entity; the binder was written for a previous Hibernate version; the annotation's attributes are accessed with wrong assumptions (empty arrays, void.class targets); binder class not public or missing a no-arg constructor.
Related errors
- Error processing @TypeBinderType annotation '%s' for embedda
- error processing @AttributeBinderType annotation '%s' for at
- Wrong kind of binder for annotation type: '%s' does not acce
- @Convert placed on @Entity/@MappedSuperclass must define att
- Collection '{}' annotated '@NotFound' is not a '@ManyToMany'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/fc8f7f804b8c1cc2.
Report an issue: GitHub.