{"record":{"id":"84487b6edbd34524","repo":"hibernate/hibernate-orm","slug":"unable-to-create-attributeconverter-instance","errorCode":null,"errorMessage":"Unable to create AttributeConverter instance","messagePattern":"Unable to create AttributeConverter instance","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/AbstractPropertyHolder.java","lineNumber":141,"sourceCode":"\n\t\t}\n\t\telse {\n\t\t\treturn new IllegalStateException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\"Unable to instantiate AttributeConverter [%s]\",\n\t\t\t\t\t\t\tinfo.getConverterClass().getName()\n\t\t\t\t\t),\n\t\t\t\t\te\n\t\t\t);\n\t\t}\n\t}\n\n\tprotected ConverterDescriptor<?,?> makeAttributeConverterDescriptor(AttributeConversionInfo conversion) {\n\t\ttry {\n\t\t\treturn ConverterDescriptors.of( conversion.getConverterClass(), null, false );\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new AnnotationException( \"Unable to create AttributeConverter instance\", e );\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean isInIdClass() {\n\t\tif ( isInIdClass != null ) {\n\t\t\treturn isInIdClass;\n\t\t}\n\t\telse if ( parent != null ) {\n\t\t\treturn parent.isInIdClass();\n\t\t}\n\t\telse {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t@Override\n\tpublic void setInIdClass(Boolean isInIdClass) {","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AbstractPropertyHolder.java#L123-L159","documentation":"AbstractPropertyHolder.makeAttributeConverterDescriptor creates the ConverterDescriptor for each @Convert(converter = ...) it processes, by calling ConverterDescriptors.of(...). That path (ClassBasedConverterDescriptor -> AbstractConverterDescriptor) resolves the converter class's AttributeConverter<X,Y> generic type arguments and reads its @Converter annotation; any failure - class does not implement AttributeConverter, unresolvable generic signature, abstract/interface class, class loading error - is wrapped in this AnnotationException with the original cause attached.","triggerScenarios":"An entity attribute carries @Convert(converter = X.class) where X is not a concrete AttributeConverter implementation, has unresolvable generic parameters, or cannot be loaded; the same happens for converters registered by class through the bootstrap API whose class shape is invalid.","commonSituations":"Refactoring that turns a converter into an interface or abstract base; copy-pasting @Convert without implementing the interface; duplicate/inconsistent converter classes on the classpath after a dependency merge; obfuscated or instrumented classes whose generic signatures are stripped.","solutions":["Inspect the attached cause (getCause()) - it names the real reflection/generics failure","Make the converter a public concrete class: public class MyConverter implements AttributeConverter<DomainType, JdbcType> with concrete type arguments","Give it a public no-arg constructor so Hibernate's bean registry can instantiate it","Verify there is exactly one MyConverter class on the classpath (check for duplicated artifacts)","For nested classes use the binary name, e.g. @Convert(converter = Outer$MyConverter.class), and declare it public static"],"exampleFix":"// before: class does not implement AttributeConverter -> boot fails\npublic class StatusConverter {                 // missing 'implements'\n    public String convertToDatabaseColumn(Status s) { ... }\n}\n@Convert(converter = StatusConverter.class)\nprivate Status status;\n\n// after\npublic class StatusConverter\n        implements AttributeConverter<Status, String> {   // concrete type args\n    @Override public String convertToDatabaseColumn(Status s) { ... }\n    @Override public Status convertToEntityAttribute(String db) { ... }\n}","handlingStrategy":"try-catch","validationCode":"// Before boot: every @Convert converter class must be a concrete AttributeConverter\nstatic boolean converterClassIsValid(Class<?> c) {\n    return AttributeConverter.class.isAssignableFrom(c)\n            && !c.isInterface()\n            && !Modifier.isAbstract(c.getModifiers())\n            && Arrays.stream(c.getConstructors()).anyMatch(ctor -> ctor.getParameterCount() == 0);\n}","typeGuard":null,"tryCatchPattern":"try {\n    sessionFactory = new MetadataSources(registry)\n            .addAnnotatedClass(MyEntity.class).buildMetadata().buildSessionFactory();\n} catch (AnnotationException e) {\n    if (e.getMessage().contains(\"Unable to create AttributeConverter instance\")) {\n        Throwable cause = e.getCause();          // real reflection failure is chained\n        throw new IllegalStateException(\"Broken @Convert converter class: \" + cause, e);\n    }\n    throw e;\n}","preventionTips":["Implement AttributeConverter<Domain,Jdbc> with real (non-wildcard, non-raw) type arguments","Keep a public no-arg constructor on every converter","Run a buildSessionFactory() smoke test in CI to catch converter wiring errors early"],"tags":["hibernate","jpa","attribute-converter","reflection","mapping","bootstrap"],"backgroundTag":"attribute-converter-instantiation-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}