{"record":{"id":"61fed493796220fc","repo":"hibernate/hibernate-orm","slug":"generator-s-declares-generated-type-s-which","errorCode":null,"errorMessage":"Generator '%s' declares generated type '%s', which is not assignable to generated attribute '%s' of type '%s'","messagePattern":"Generator '(.+?)' declares generated type '(.+?)', which is not assignable to generated attribute '(.+?)' of type '(.+?)'","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/generator/internal/GeneratorTypeHelper.java","lineNumber":32,"sourceCode":"import static org.hibernate.internal.util.PrimitiveHelper.boxedType;\n\n@Internal\npublic final class GeneratorTypeHelper {\n\tpublic static void checkGeneratorGeneratedType(Generator generator, GeneratorCreationContext context) {\n\t\tfinal var generatedType = generator.getGeneratedType();\n\t\tif ( generatedType != null ) {\n\t\t\tfinal var property = context.getProperty();\n\t\t\tif ( property != null ) {\n\t\t\t\tcheckAssignable( generator, generatedType, context );\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static void checkAssignable(Generator generator, Class<?> generatedType, GeneratorCreationContext context) {\n\t\tfinal var attributeType = context.getType().getReturnedClass();\n\t\tif ( attributeType != null\n\t\t\t\t&& !boxedType( attributeType ).isAssignableFrom( boxedType( generatedType ) ) ) {\n\t\t\tthrow new MappingException( String.format(\n\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\"Generator '%s' declares generated type '%s', which is not assignable to generated attribute '%s' of type '%s'\",\n\t\t\t\t\tgenerator.getClass().getName(),\n\t\t\t\t\tgeneratedType.getTypeName(),\n\t\t\t\t\tattributePath( context ),\n\t\t\t\t\tattributeType.getTypeName()\n\t\t\t) );\n\t\t}\n\t}\n\n\tprivate static String attributePath(GeneratorCreationContext context) {\n\t\tfinal var property = context.getProperty();\n\t\tfinal var persistentClass = context.getPersistentClass();\n\t\tif ( persistentClass != null && property != null ) {\n\t\t\treturn persistentClass.getEntityName() + \".\" + property.getName();\n\t\t}\n\n\t\tfinal var memberDetails = context.getMemberDetails();","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/generator/internal/GeneratorTypeHelper.java#L14-L50","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before — generator produces UUID, attribute is Long\n@Id\n@MyUuidGenerator\nLong id;\n\n// after — attribute type matches the generated type\n@Id\n@MyUuidGenerator\nUUID id;","handlingStrategy":"type-guard","validationCode":"@Test\nvoid generatorMatchesAttributeTypes() throws Exception {\n    MyUuidGenerator g = new MyUuidGenerator();\n    assertEquals(UUID.class, g.getGeneratedType());\n    assertEquals(UUID.class, Document.class.getDeclaredField(\"id\").getType());\n}","typeGuard":"static boolean generatorCompatible(Generator generator, Class<?> attributeJavaType) {\n    final Class<?> generated = generator.getGeneratedType();\n    return generated == null || attributeJavaType == null\n            || box(attributeJavaType).isAssignableFrom(box(generated));\n}\n\nstatic Class<?> box(Class<?> t) {\n    if (!t.isPrimitive()) return t;\n    if (t == int.class) return Integer.class;\n    if (t == long.class) return Long.class;\n    if (t == boolean.class) return Boolean.class;\n    if (t == double.class) return Double.class;\n    if (t == float.class) return Float.class;\n    if (t == short.class) return Short.class;\n    if (t == byte.class) return Byte.class;\n    return Character.class;\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["hibernate","generator","type-mismatch","id-generation","mapping","bootstrap"],"backgroundTag":"generator-type-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}