{"record":{"id":"fc8f7f804b8c1cc2","repo":"hibernate/hibernate-orm","slug":"error-processing-typebindertype-annotation-s-f-fc8f7f","errorCode":null,"errorMessage":"Error processing @TypeBinderType annotation '%s' for entity type '%s'","messagePattern":"Error processing @TypeBinderType annotation '(.+?)' for entity type '(.+?)'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/Binders.java","lineNumber":52,"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 embeddable type '%s'\"\n\t\t\t\t\t\t\t.formatted( annotation, embeddable.getComponentClassName() ), e );\n\t\t}\n\t}\n\n\tstatic <A extends Annotation> void callTypeBinder(\n\t\t\tAnnotation annotation, Class<A> annotationType,\n\t\t\tPersistentClass entity,\n\t\t\tMetadataBuildingContext context) {\n\t\ttry {\n\t\t\ttypeBinder( annotationType )\n\t\t\t\t\t.bind( annotationType.cast( annotation ),\n\t\t\t\t\t\t\tcontext, entity );\n\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 );","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/Binders.java#L34-L70","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\npublic class AuditBinder implements TypeBinder<Audited> {\n    public void bind(Audited ann, MetadataBuildingContext ctx, PersistentClass entity) {\n        entity.getTable().getColumn( ann.column() ).setNullable( false ); // throws if column absent\n    }\n}\n\n// after\npublic class AuditBinder implements TypeBinder<Audited> {\n    public void bind(Audited ann, MetadataBuildingContext ctx, PersistentClass entity) {\n        Column col = entity.getTable().getColumn( ann.column() );\n        if ( col == null ) {\n            throw new IllegalArgumentException( \"Entity \" + entity.getClassName()\n                + \" has no column \" + ann.column() + \" for @Audited\" );\n        }\n        col.setNullable( false );\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 binder failed for entity during bootstrap: \"\n        + cause.getMessage(), cause );\n}","preventionTips":["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"],"tags":["hibernate","jpa","annotation-binding","custom-type","entity","typebinder"],"backgroundTag":"custom-annotation-binder-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}