{"record":{"id":"876f86e02d9077ba","repo":"hibernate/hibernate-orm","slug":"custom-type-s-implements-annotationbaseduserty","errorCode":null,"errorMessage":"Custom type '%s' implements 'AnnotationBasedUserType' but no custom type annotation is present","messagePattern":"Custom type '(.+?)' implements 'AnnotationBasedUserType' but no custom type annotation is present","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java","lineNumber":1155,"sourceCode":"\t\t\tinitializeAnnotationBasedUserType( typeAnnotation, annotationBased, creationContext );\n\t\t}\n\t\treturn typeInstance;\n\t}\n\n\tprivate void addParameterType(Properties properties, UserType<?> typeInstance) {\n\t\tif ( typeInstance instanceof DynamicParameterizedType\n\t\t\t\t&& parseBoolean( properties.getProperty( DynamicParameterizedType.IS_DYNAMIC ) )\n\t\t\t\t&& properties.get( DynamicParameterizedType.PARAMETER_TYPE ) == null ) {\n\t\t\tproperties.put( DynamicParameterizedType.PARAMETER_TYPE, createParameterType() );\n\t\t}\n\t}\n\n\tprivate <A extends Annotation> void initializeAnnotationBasedUserType(\n\t\t\tAnnotation typeAnnotation,\n\t\t\tAnnotationBasedUserType<A, ?> annotationBased,\n\t\t\tUserTypeCreationContext creationContext) {\n\t\tif ( typeAnnotation == null ) {\n\t\t\tthrow new AnnotationException( String.format(\n\t\t\t\t\t\"Custom type '%s' implements 'AnnotationBasedUserType' but no custom type annotation is present\",\n\t\t\t\t\tannotationBased.getClass().getName() ) );\n\t\t}\n\t\tannotationBased.initialize( castAnnotationType( typeAnnotation, annotationBased ), creationContext );\n\t}\n\n\tprivate class TypeCreationContext implements UserTypeCreationContext {\n\t\tprivate final Properties parameters;\n\n\t\tprivate TypeCreationContext(Properties parameters) {\n\t\t\tthis.parameters = parameters;\n\t\t}\n\n\t\t@Override\n\t\tpublic MetadataBuildingContext getBuildingContext() {\n\t\t\treturn BasicValue.this.getBuildingContext();\n\t\t}\n","sourceCodeStart":1137,"sourceCodeEnd":1173,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java#L1137-L1173","documentation":"UserTypes implementing AnnotationBasedUserType<A, ?> are initialized with the type annotation found on the mapped attribute. When no such annotation is present (typeAnnotation == null), Hibernate throws AnnotationException naming the custom type class, since initialize(...) cannot run without configuration.","triggerScenarios":"@CustomType(MyType.class) where MyType implements AnnotationBasedUserType<MyAnn, ?> but the attribute carries no @MyAnn; registering such a type via plain @Type/@TypeDef so the annotation never reaches it; attribute carrying only unrelated annotations.","commonSituations":"Adopting Hibernate 6.2+ annotation-based custom types incrementally; frameworks applying custom types centrally without the paired annotation; copying a custom type declaration without its annotation.","solutions":["Annotate the attribute with the annotation the custom type declares (e.g., @MyAnn with its parameters).","If the type needs no annotation configuration, drop AnnotationBasedUserType from its interfaces.","When applying types centrally, also transfer the expected annotation onto each attribute."],"exampleFix":"// before: type implements AnnotationBasedUserType<Formatted, ?>\n@CustomType(FormattedStringType.class)\nprivate String note;\n\n// after\n@Formatted(uppercase = true)\n@CustomType(FormattedStringType.class)\nprivate String note;","handlingStrategy":"validation","validationCode":"static boolean annotationPresent( Field f, Class<? extends Annotation> expected ) {\n    return f.isAnnotationPresent( expected );\n}\n// for each @CustomType attribute, assert the annotation declared by its AnnotationBasedUserType is present","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair every annotation-based custom type with its annotation in one shared meta-annotation","Do not apply AnnotationBasedUserType implementations via plain @Type/@TypeDef","Add an architecture test that checks @CustomType attributes carry their expected annotation"],"tags":["hibernate","custom-type","annotations"],"backgroundTag":"annotation-misconfiguration","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}