hibernate/hibernate-orm · error · MappingException
Generator '%s' declares generated type '%s', which is not as
Error message
Generator '%s' declares generated type '%s', which is not assignable to generated attribute '%s' of type '%s'
What it means
When a Generator declares the type of value it produces (getGeneratedType() returns a non-null Class), Hibernate validates at bootstrap that the produced type is assignable to the attribute the generator is attached to (boxing-aware via boxedType). If, for example, a UUID-producing generator is attached to a Long id, this MappingException is thrown, naming the generator class, generated type, attribute path, and attribute type.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/generator/internal/GeneratorTypeHelper.java:32
import static org.hibernate.internal.util.PrimitiveHelper.boxedType;
@Internal
public final class GeneratorTypeHelper {
public static void checkGeneratorGeneratedType(Generator generator, GeneratorCreationContext context) {
final var generatedType = generator.getGeneratedType();
if ( generatedType != null ) {
final var property = context.getProperty();
if ( property != null ) {
checkAssignable( generator, generatedType, context );
}
}
}
private static void checkAssignable(Generator generator, Class<?> generatedType, GeneratorCreationContext context) {
final var attributeType = context.getType().getReturnedClass();
if ( attributeType != null
&& !boxedType( attributeType ).isAssignableFrom( boxedType( generatedType ) ) ) {
throw new MappingException( String.format(
Locale.ROOT,
"Generator '%s' declares generated type '%s', which is not assignable to generated attribute '%s' of type '%s'",
generator.getClass().getName(),
generatedType.getTypeName(),
attributePath( context ),
attributeType.getTypeName()
) );
}
}
private static String attributePath(GeneratorCreationContext context) {
final var property = context.getProperty();
final var persistentClass = context.getPersistentClass();
if ( persistentClass != null && property != null ) {
return persistentClass.getEntityName() + "." + property.getName();
}
final var memberDetails = context.getMemberDetails();View on GitHub (pinned to fad1729dce)
Solutions
- Align the types: change the attribute to the generated type (Long id -> UUID id) or change the generator to produce the attribute's type
- If one generator must serve several attribute types, return null from getGeneratedType() to opt out of the static check and generate values matching each attribute
- Pick the built-in generator matching the attribute type (@UuidGenerator for UUID, sequence/identity for integral ids)
- Add a unit test asserting getGeneratedType() is assignable to every attribute carrying your generator annotation
Example fix
// before — generator produces UUID, attribute is Long @Id @MyUuidGenerator Long id; // after — attribute type matches the generated type @Id @MyUuidGenerator UUID id;
Defensive patterns
Strategy: type-guard
Validate before calling
@Test
void generatorMatchesAttributeTypes() throws Exception {
MyUuidGenerator g = new MyUuidGenerator();
assertEquals(UUID.class, g.getGeneratedType());
assertEquals(UUID.class, Document.class.getDeclaredField("id").getType());
} Type guard
static boolean generatorCompatible(Generator generator, Class<?> attributeJavaType) {
final Class<?> generated = generator.getGeneratedType();
return generated == null || attributeJavaType == null
|| box(attributeJavaType).isAssignableFrom(box(generated));
}
static Class<?> box(Class<?> t) {
if (!t.isPrimitive()) return t;
if (t == int.class) return Integer.class;
if (t == long.class) return Long.class;
if (t == boolean.class) return Boolean.class;
if (t == double.class) return Double.class;
if (t == float.class) return Float.class;
if (t == short.class) return Short.class;
if (t == byte.class) return Byte.class;
return Character.class;
} Prevention
- Derive getGeneratedType() from the value you actually generate, or return null when the generator is type-agnostic
- Keep one generator annotation per attribute type
- Cover every generator/attribute pairing with a bootstrap or unit test
When it happens
Trigger: Attaching a generator whose declared type mismatches the attribute: a custom Generator via @IdGeneratorType or generator strategies — e.g. UUID generator on a Long id, Integer generator on a String field, java.util.Date generator on a java.time.Instant attribute.
Common situations: Writing the first custom @IdGeneratorType annotation by copying an example written for another attribute type; changing an entity field type without updating its generator; applying one custom generator annotation to several entities whose id types differ.
Related errors
- illegal identity column type
- Attribute was not a Map : ${collectionMemberType}
- Unable to create AttributeConverter instance
- Identifier attribute '%s' of entity '%s' has type '%s' but i
- dialect does not support sequences
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/61fed493796220fc.
Report an issue: GitHub.