{"record":{"id":"d90c5a0fc59ea499","repo":"hibernate/hibernate-orm","slug":"annotation-s-is-not-assignable-to-s-d90c5a","errorCode":null,"errorMessage":"Annotation '%s' is not assignable to '%s'","messagePattern":"Annotation '(.+?)' is not assignable to '(.+?)'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java","lineNumber":1200,"sourceCode":"\t\t}\n\n\t\t@Override\n\t\tpublic Properties getParameters() {\n\t\t\treturn parameters;\n\t\t}\n\t}\n\n\tprivate static <A extends Annotation> A castAnnotationType(\n\t\t\tAnnotation typeAnnotation, AnnotationBasedUserType<A, ?> annotationBased ) {\n\t\tfinal var annotationType = annotationBased.getClass();\n\t\tfor ( var iface: annotationType.getGenericInterfaces() ) {\n\t\t\tif ( iface instanceof ParameterizedType parameterizedType\n\t\t\t\t\t&& parameterizedType.getRawType() == AnnotationBasedUserType.class ) {\n\t\t\t\tfinal var typeArguments = parameterizedType.getActualTypeArguments();\n\t\t\t\tif ( typeArguments.length > 0\n\t\t\t\t\t&& typeArguments[0] instanceof Class<?> annotationClass ) {\n\t\t\t\t\tif ( !annotationClass.isInstance( typeAnnotation ) ) {\n\t\t\t\t\t\tthrow new AnnotationException( String.format( \"Annotation '%s' is not assignable to '%s'\",\n\t\t\t\t\t\t\t\tannotationType.getName(), iface.getTypeName() ) );\n\t\t\t\t\t}\n\t\t\t\t\t@SuppressWarnings(\"unchecked\") // safe, we just checked it\n\t\t\t\t\tfinal var castAnnotation = (A) typeAnnotation;\n\t\t\t\t\treturn castAnnotation;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthrow new AssertionFailure( \"Could not find implementing interface\" );\n\t}\n\n\tprivate <T extends UserType<?>, A extends Annotation> T instantiateUserType(\n\t\t\tClass<T> customType, A typeAnnotation,\n\t\t\tUserTypeCreationContext creationContext) {\n\t\ttry {\n\t\t\tT userType;\n\t\t\tif ( typeAnnotation != null ) {\n\t\t\t\t@SuppressWarnings(\"unchecked\") // totally safe","sourceCodeStart":1182,"sourceCodeEnd":1218,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java#L1182-L1218","documentation":"castAnnotationType verifies that the attribute's type annotation is an instance of the first type argument of the AnnotationBasedUserType<A, ?> interface implemented by the custom type. A mismatched annotation triggers AnnotationException before the unsafe cast; the message names the custom type class and the interface type.","triggerScenarios":"Custom type implements AnnotationBasedUserType<MyAnn, ?> but the attribute carries a different custom annotation (@OtherAnn); multiple type annotations present where the wrong one is picked; refactoring the generic parameter without updating mappings.","commonSituations":"Renamed or repackaged annotation classes; two similar annotation-based types applied together; copy-paste of @CustomType without the matching annotation.","solutions":["Put the exact annotation matching the generic parameter on the attribute.","Update the custom type's AnnotationBasedUserType<A, ...> parameter to the annotation actually used.","Remove stray type annotations from the attribute so the right one is selected."],"exampleFix":"// before\n@OtherFormat\n@CustomType(MyFormatType.class) // implements AnnotationBasedUserType<MyFormat, ?>\nprivate String value;\n\n// after\n@MyFormat(style = \"short\")\n@CustomType(MyFormatType.class)\nprivate String value;","handlingStrategy":"validation","validationCode":"static boolean annotationMatches( Class<? extends Annotation> found,\n        Class<? extends AnnotationBasedUserType<?, ?>> userType ) {\n    for ( var iface : userType.getGenericInterfaces() ) {\n        if ( iface instanceof ParameterizedType pt\n                && pt.getRawType() == AnnotationBasedUserType.class\n                && pt.getActualTypeArguments()[0] instanceof Class<?> expected ) {\n            return expected.isAssignableFrom( found );\n        }\n    }\n    return false;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the custom type and its annotation in the same package and change them together","Apply only one type annotation per attribute","Unit-test the pairing of custom types with their annotations at bootstrap"],"tags":["hibernate","custom-type","annotations","type-mismatch"],"backgroundTag":"annotation-misconfiguration","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}