{"record":{"id":"9e9f02cb733a8d7b","repo":"hibernate/hibernate-orm","slug":"the-id-attribute-is-not-declared-on-this-type","errorCode":null,"errorMessage":"The id attribute is not declared on this type [{}]","messagePattern":"The id attribute is not declared on this type \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java","lineNumber":177,"sourceCode":"\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() + \"]\" );\n\t\t}\n\t\tcheckType( id, javaType );\n\t\t@SuppressWarnings(\"unchecked\") // safe, we just checked\n\t\tfinal var castId = (SqmSingularPersistentAttribute<J, Y>) id;\n\t\treturn castId;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic SimpleDomainType<?> getIdType() {\n\t\tfinal var id = findIdAttribute();\n\t\tif ( id != null ) {\n\t\t\treturn id.getType();\n\t\t}\n\t\telse {\n\t\t\tfinal var idClassAttributes = getIdClassAttributesSafely();\n\t\t\tif ( idClassAttributes != null ) {\n\t\t\t\tif ( idClassAttributes.size() == 1 ) {","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java#L159-L195","documentation":"getDeclaredId(Class) returns only attributes declared directly on the queried type, never inherited ones. If this type has no id attribute of its own (field id == null — typically because the id is declared on a @MappedSuperclass or an entity superclass), Hibernate throws IllegalArgumentException. Use getId(Class) to search the hierarchy.","triggerScenarios":"Calling getDeclaredId(...) on a subclass entity whose @Id sits in an abstract @MappedSuperclass base class; calling it on a subtype that inherits its id from a root entity in JOINED/ TABLE_PER_CLASS inheritance.","commonSituations":"Base-entity patterns like AbstractEntity<T> with the @Id in it; all concrete entities then fail getDeclaredId. Generic frameworks calling the declared variant unconditionally. Copying getId code and switching to the declared variant to avoid duplicates.","solutions":["Use getId(Class) instead — it resolves inherited ids via findIdAttribute() walking the supertype chain","Keep the @Id on the concrete entity if you truly need getDeclaredId semantics","Guard first: if (type.getDeclaredId(...) needed) check type has no superType declaring the id, or call findDeclaredId()-style lookup if available"],"exampleFix":"// before\nvar id = subtypeType.getDeclaredId(Long.class); // id lives on AbstractEntity -> throws\n\n// after\nvar id = subtypeType.getId(Long.class); // walks supertype chain","handlingStrategy":"validation","validationCode":"// Use hierarchy-aware lookup unless you truly need declared-only\nSingularAttribute<? super E, ?> id = identifiableType.getId(javaType); // searches supertypes\n// or check first:\nif (identifiableType.getSupertype() instanceof IdentifiableType<?>) { /* id may be inherited */ }","typeGuard":null,"tryCatchPattern":"try {\n    return type.getDeclaredId(cls);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"not declared on this type\")) {\n        return type.getId(cls); // fall back to inherited\n    }\n    throw e;\n}","preventionTips":["Default to getId() in generic code; use getDeclaredId() only when you must distinguish own vs inherited members","Know where your @Id lives — base @MappedSuperclass means all concrete types fail getDeclaredId","Wrap metamodel lookups in one helper so fallback policy is centralized"],"tags":["hibernate","jpa-metamodel","mapped-superclass","inheritance","id-attribute"],"backgroundTag":"jpa-metamodel-declared-vs-inherited","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}