{"record":{"id":"c4cf49134967656a","repo":"hibernate/hibernate-orm","slug":"error-processing-typebindertype-annotation-s-f","errorCode":null,"errorMessage":"Error processing @TypeBinderType annotation '%s' for embeddable type '%s'","messagePattern":"Error processing @TypeBinderType annotation '(.+?)' for embeddable type '(.+?)'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/Binders.java","lineNumber":36,"sourceCode":"\nimport static org.hibernate.internal.util.GenericsHelper.typeArguments;\n\n/**\n * @author Gavin King\n * @since 7.3\n */\npublic class Binders {\n\tstatic <A extends Annotation> void callTypeBinder(\n\t\t\tAnnotation annotation, Class<A> annotationType,\n\t\t\tComponent embeddable,\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, embeddable );\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 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 );","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/Binders.java#L18-L54","documentation":"Hibernate throws this AnnotationException while binding an @Embeddable 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 (or while instantiating the binder) is attached as the cause. Fix the cause, not this message.","triggerScenarios":"A user-defined annotation meta-annotated with @TypeBinderType is placed on an @Embeddable class. During metadata building Binders.callTypeBinder(Annotation, Class<A>, Component, MetadataBuildingContext) reflects the binder, instantiates it, and calls bind(annotation, context, embeddable); any exception from bind(), from the no-arg constructor, or from the type-argument check is caught and rethrown wrapped in this message.","commonSituations":"A custom TypeBinder written for entities is reused on embeddables and calls entity-only APIs; the binder dereferences null annotation attributes or an unpopulated Component; the binder class lacks a public no-arg constructor; a Hibernate upgrade changed the TypeBinder API so old binder code throws NoSuchMethodError or similar.","solutions":["Inspect the exception cause chain (getCause()) - the real failure is inside your TypeBinder.bind() implementation, not in Hibernate","Step through your binder in a debugger during Metadata/SessionFactory build to find the failing line","Make the binder handle the Component (embeddable) case, not just PersistentClass/entity","Give the binder class a public no-arg constructor and verify its generic type argument matches the annotation type"],"exampleFix":"// before\npublic class TenantIdBinder implements TypeBinder<TenantScoped> {\n    public void bind(TenantScoped ann, MetadataBuildingContext ctx, Component embeddable) {\n        // NPE when the embeddable has no owner set yet\n        embeddable.getOwner().getTable().addColumn( column( ann ) );\n    }\n}\n\n// after\npublic class TenantIdBinder implements TypeBinder<TenantScoped> {\n    public void bind(TenantScoped ann, MetadataBuildingContext ctx, Component embeddable) {\n        if ( embeddable.getOwner() == null ) {\n            throw new IllegalArgumentException(\n                \"@TenantScoped requires the embeddable to have an owner\" );\n        }\n        embeddable.getOwner().getTable().addColumn( column( ann ) );\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    SessionFactory sf = metadata.getSessionFactoryBuilder().build();\n}\ncatch ( AnnotationException e ) {\n    // the binder's real failure is nested - unwrap and report the cause\n    Throwable cause = e.getCause() != null ? e.getCause() : e;\n    throw new IllegalStateException( \"Custom @TypeBinderType binder failed during bootstrap: \"\n        + cause.getMessage(), cause );\n}","preventionTips":["Write a unit test that builds Metadata with only the annotated embeddable, so binder failures fail the build","Never let binder code throw bare NPEs - validate annotation attributes and metadata state and throw descriptive IllegalArgumentExceptions","Keep one binder per annotation type with a matching generic argument and a public no-arg constructor","Re-run the mapping smoke test after every Hibernate version upgrade before deploying"],"tags":["hibernate","jpa","annotation-binding","custom-type","embeddable","typebinder"],"backgroundTag":"custom-annotation-binder-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}