{"record":{"id":"dd6af64a6ca9b986","repo":"hibernate/hibernate-orm","slug":"error-processing-attributebindertype-annotation","errorCode":null,"errorMessage":"error processing @AttributeBinderType annotation '%s' for attribute '%s' of entity type '%s'","messagePattern":"error processing @AttributeBinderType annotation '(.+?)' for attribute '(.+?)' of entity type '(.+?)'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/Binders.java","lineNumber":68,"sourceCode":"\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new AnnotationException(\n\t\t\t\t\t\"Error processing @TypeBinderType annotation '%s' for entity type '%s'\"\n\t\t\t\t\t\t\t.formatted( annotation, entity.getClassName() ), e );\n\t\t}\n\t}\n\n\tstatic <A extends Annotation> void callPropertyBinder(\n\t\t\tAnnotation annotation, Class<A> annotationType,\n\t\t\tPersistentClass entity, Property property,\n\t\t\tMetadataBuildingContext context) {\n\t\ttry {\n\t\t\tpropertyBinder( annotationType )\n\t\t\t\t\t.bind( annotationType.cast( annotation ),\n\t\t\t\t\t\t\tcontext, entity, property );\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new AnnotationException(\n\t\t\t\t\t\"error processing @AttributeBinderType annotation '%s' for attribute '%s' of entity type '%s'\"\n\t\t\t\t\t\t\t.formatted( annotation, property.getName(), entity.getClassName() ), e );\n\t\t}\n\t}\n\n\tprivate static <A extends Annotation> TypeBinder<A> typeBinder(Class<A> annotationType)\n\t\t\tthrows Exception {\n\t\tfinal var binderType =\n\t\t\t\tannotationType.getAnnotation( TypeBinderType.class )\n\t\t\t\t\t\t.binder();\n\t\tcheckImplementedTypeArgument( annotationType, binderType, TypeBinder.class );\n\t\t@SuppressWarnings(\"unchecked\") // Safe, we just checked\n\t\tfinal var castBinderType = (Class<? extends TypeBinder<A>>) binderType;\n\t\treturn castBinderType.getDeclaredConstructor().newInstance();\n\t}\n\n\tprivate static <A extends Annotation> AttributeBinder<A> propertyBinder(Class<A> annotationType)\n\t\t\t\t\tthrows Exception {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/Binders.java#L50-L86","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the exception cause chain (getCause()) - the real failure is inside your AttributeBinder.bind() implementation","Step through the binder during Metadata build in a test to locate the failing line","Type-check property.getValue() (BasicValue vs association) inside the binder and throw a precise message for unsupported cases","Ensure the binder class has a public no-arg constructor and a generic argument matching the annotation"],"exampleFix":"// before\npublic class ValidityBinder implements AttributeBinder<ValidUntil> {\n    public void bind(ValidUntil ann, MetadataBuildingContext ctx,\n                     PersistentClass entity, Property property) {\n        BasicValue value = (BasicValue) property.getValue(); // ClassCastException on associations\n        value.setJpaAttributeConverter( ... );\n    }\n}\n\n// after\npublic class ValidityBinder implements AttributeBinder<ValidUntil> {\n    public void bind(ValidUntil ann, MetadataBuildingContext ctx,\n                     PersistentClass entity, Property property) {\n        if ( ! ( property.getValue() instanceof BasicValue basic ) ) {\n            throw new IllegalArgumentException( \"@ValidUntil only applies to basic attributes: \"\n                + entity.getClassName() + \".\" + property.getName() );\n        }\n        configure( basic, ann );\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    SessionFactory sf = metadata.getSessionFactoryBuilder().build();\n}\ncatch ( AnnotationException e ) {\n    Throwable cause = e.getCause() != null ? e.getCause() : e;\n    throw new IllegalStateException( \"Custom @AttributeBinderType binder failed during bootstrap: \"\n        + cause.getMessage(), cause );\n}","preventionTips":["Add a mapping smoke test covering every entity class that uses custom attribute annotations","instanceof-check property.getValue() in binders before casting; reject unsupported kinds with clear messages","Cover the binder with a direct unit test that passes a real Property and PersistentClass","Unwrap and read the cause chain whenever a binder wrapper error appears - the message alone never identifies the bug"],"tags":["hibernate","jpa","annotation-binding","custom-type","attribute","attributebinder"],"backgroundTag":"custom-annotation-binder-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}