{"record":{"id":"a9696068d5e5ecbd","repo":"hibernate/hibernate-orm","slug":"attribute-s-s-s-not-castable-to-requested-t","errorCode":null,"errorMessage":"Attribute [%s#%s : %s] not castable to requested type [%s]","messagePattern":"Attribute \\[(.+?)#(.+?) : (.+?)\\] not castable to requested type \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java","lineNumber":159,"sourceCode":"\n\t@Override\n\tpublic @Nullable SqmSingularPersistentAttribute<? super J, ?> findIdAttribute() {\n\t\tif ( id != null ) {\n\t\t\treturn id;\n\t\t}\n\t\telse if ( getSuperType() != null ) {\n\t\t\treturn getSuperType().findIdAttribute();\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate void checkType(SingularPersistentAttribute<?, ?> attribute, Class<?> javaType) {\n\t\tif ( !javaType.isAssignableFrom( attribute.getType().getJavaType() ) ) {\n\t\t\tif ( !( attribute.getAttributeJavaType() instanceof PrimitiveJavaType<?> primitiveJavaType )\n\t\t\t\t\t|| primitiveJavaType.getPrimitiveClass() != javaType ) {\n\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\t\"Attribute [%s#%s : %s] not castable to requested type [%s]\",\n\t\t\t\t\t\t\t\tgetTypeName(),\n\t\t\t\t\t\t\t\tattribute.getName(),\n\t\t\t\t\t\t\t\tattribute.getType().getJavaType().getName(),\n\t\t\t\t\t\t\t\tjavaType.getName()\n\t\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <Y> SqmSingularPersistentAttribute<J, Y> getDeclaredId(@Nonnull Class<Y> javaType) {\n\t\tensureNoIdClass();\n\t\tif ( id == null ) {\n\t\t\tthrow new IllegalArgumentException( \"The id attribute is not declared on this type [\" + getTypeName() + \"]\" );","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java#L141-L177","documentation":"When you ask the metamodel for an id or version attribute with an explicit Java type — getId(Class), getDeclaredId(Class), getVersion(Class), getDeclaredVersion(Class) — Hibernate checks that the requested type is assignable from the attribute's actual type (with a special allowance for the matching primitive wrapper). If the class you passed does not match, it throws IllegalArgumentException naming the attribute, its real type, and the requested type.","triggerScenarios":"Calling getId(String.class) when the id is Long; getVersion(int.class) when the version is Long (primitive check only passes if the primitive class matches exactly); getDeclaredId(UUID.class) on an entity whose id is a primitive long.","commonSituations":"Assuming id type across entities in generic code (e.g. always requesting Long.class while some entities use String or UUID ids). Refactoring an id from Long to UUID and stale metamodel calls. Primitive vs wrapper confusion (int vs Integer fails: the primitive escape-hatch only accepts the exact primitive class).","solutions":["Pass the exact declared type: read id.getType().getJavaType() or use findIdAttribute() first and derive the type from the attribute instead of guessing","Prefer the no-type lookups (findIdAttribute(), findVersionAttribute()) and cast after inspecting the Java type","If refactoring changed the id type, update every getId(Class) call site — the message shows actual vs requested type"],"exampleFix":"// before\nSingularAttribute<? super User, Long> id = userType.getId(Long.class); // id is actually String\n\n// after\nSingularAttribute<? super User, ?> idAttr = userType.getId(userType.getIdType().getJavaType());\n// or: Class<?> idJavaType = userType.getIdType().getJavaType();","handlingStrategy":"validation","validationCode":"// Derive the correct class from the metamodel instead of guessing\nClass<?> actual = attribute.getType().getJavaType();\nif (!requestedType.isAssignableFrom(actual)\n        && actual != wrap(requestedType) /* primitive pair */) {\n    throw new IllegalArgumentException(\"wrong type requested for \" + attribute.getName());\n}","typeGuard":null,"tryCatchPattern":"try {\n    return type.getId(expected);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"not castable to requested type\")) {\n        Class<?> real = type.getIdType().getJavaType();\n        return type.getId((Class) real);\n    }\n    throw e;\n}","preventionTips":["Read the id/version Java type from the metamodel rather than hard-coding Long/String","After changing an id or version field type, grep for getId(/getVersion( call sites","Remember int.class is only accepted for int ids — Integer.class fails for primitive int and vice versa in the primitive branch"],"tags":["hibernate","jpa-metamodel","type-mismatch","id-attribute","version-attribute"],"backgroundTag":"jpa-metamodel-type-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}