hibernate/hibernate-orm · error · AnnotationException

error processing @AttributeBinderType annotation

Error message

error processing @AttributeBinderType annotation '%s' for attribute '%s' of entity type '%s'

What it means

Hibernate throws this AnnotationException while binding a property when a custom attribute binder registered through @AttributeBinderType fails. The exception only wraps the real failure: the original exception thrown inside your AttributeBinder.bind() implementation is attached as the cause. The message names the annotation, the attribute, and the entity.

Solutions

  1. Inspect the exception cause chain (getCause()) - the real failure is inside your AttributeBinder.bind() implementation
  2. Step through the binder during Metadata build in a test to locate the failing line
  3. Type-check property.getValue() (BasicValue vs association) inside the binder and throw a precise message for unsupported cases
  4. Ensure the binder class has a public no-arg constructor and a generic argument matching the annotation

Example fix

// before
public class ValidityBinder implements AttributeBinder<ValidUntil> {
    public void bind(ValidUntil ann, MetadataBuildingContext ctx,
                     PersistentClass entity, Property property) {
        BasicValue value = (BasicValue) property.getValue(); // ClassCastException on associations
        value.setJpaAttributeConverter( ... );
    }
}

// after
public class ValidityBinder implements AttributeBinder<ValidUntil> {
    public void bind(ValidUntil ann, MetadataBuildingContext ctx,
                     PersistentClass entity, Property property) {
        if ( ! ( property.getValue() instanceof BasicValue basic ) ) {
            throw new IllegalArgumentException( "@ValidUntil only applies to basic attributes: "
                + entity.getClassName() + "." + property.getName() );
        }
        configure( basic, ann );
    }
}
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 @AttributeBinderType binder failed during bootstrap: "
        + cause.getMessage(), cause );
}

Prevention

When it happens

Trigger: A user-defined annotation meta-annotated with @AttributeBinderType is placed on a persistent attribute. During metadata building Binders.callPropertyBinder(Annotation, Class<A>, PersistentClass, Property, MetadataBuildingContext) instantiates the binder and calls bind(annotation, context, entity, property); any exception from bind() or binder instantiation is caught and rethrown wrapped in this message.

Common situations: The binder assumes a basic-valued property but receives an association or component; the binder mutates metadata that is not yet initialized at that binding stage; binder written against an older AttributeBinder signature; missing no-arg constructor.

Related errors


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

Appendix: source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/Binders.java:68

		}
		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 );
		}
	}

	private static <A extends Annotation> TypeBinder<A> typeBinder(Class<A> annotationType)
			throws Exception {
		final var binderType =
				annotationType.getAnnotation( TypeBinderType.class )
						.binder();
		checkImplementedTypeArgument( annotationType, binderType, TypeBinder.class );
		@SuppressWarnings("unchecked") // Safe, we just checked
		final var castBinderType = (Class<? extends TypeBinder<A>>) binderType;
		return castBinderType.getDeclaredConstructor().newInstance();
	}

	private static <A extends Annotation> AttributeBinder<A> propertyBinder(Class<A> annotationType)
					throws Exception {

View on GitHub (pinned to fad1729dce)