hibernate/hibernate-orm · error · AnnotationException
Unable to create AttributeConverter instance
Error message
Unable to create AttributeConverter instance
What it means
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.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/AbstractPropertyHolder.java:141
}
else {
return new IllegalStateException(
String.format(
"Unable to instantiate AttributeConverter [%s]",
info.getConverterClass().getName()
),
e
);
}
}
protected ConverterDescriptor<?,?> makeAttributeConverterDescriptor(AttributeConversionInfo conversion) {
try {
return ConverterDescriptors.of( conversion.getConverterClass(), null, false );
}
catch (Exception e) {
throw new AnnotationException( "Unable to create AttributeConverter instance", e );
}
}
@Override
public boolean isInIdClass() {
if ( isInIdClass != null ) {
return isInIdClass;
}
else if ( parent != null ) {
return parent.isInIdClass();
}
else {
return false;
}
}
@Override
public void setInIdClass(Boolean isInIdClass) {View on GitHub (pinned to fad1729dce)
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
Example fix
// before: class does not implement AttributeConverter -> boot fails
public class StatusConverter { // missing 'implements'
public String convertToDatabaseColumn(Status s) { ... }
}
@Convert(converter = StatusConverter.class)
private Status status;
// after
public class StatusConverter
implements AttributeConverter<Status, String> { // concrete type args
@Override public String convertToDatabaseColumn(Status s) { ... }
@Override public Status convertToEntityAttribute(String db) { ... }
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before boot: every @Convert converter class must be a concrete AttributeConverter
static boolean converterClassIsValid(Class<?> c) {
return AttributeConverter.class.isAssignableFrom(c)
&& !c.isInterface()
&& !Modifier.isAbstract(c.getModifiers())
&& Arrays.stream(c.getConstructors()).anyMatch(ctor -> ctor.getParameterCount() == 0);
} Try / catch
try {
sessionFactory = new MetadataSources(registry)
.addAnnotatedClass(MyEntity.class).buildMetadata().buildSessionFactory();
} catch (AnnotationException e) {
if (e.getMessage().contains("Unable to create AttributeConverter instance")) {
Throwable cause = e.getCause(); // real reflection failure is chained
throw new IllegalStateException("Broken @Convert converter class: " + cause, e);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- AttributeConverter class [%s] registered multiple times
- Attribute was not a Map : ${collectionMemberType}
- Unable to build Hibernate SessionFactory [persistence unit:
- Could not resolve PropertyAccess for attribute `%s#%s`
- Could not resolve PropertyAccess for attribute `%s#%s`
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/84487b6edbd34524.
Report an issue: GitHub.