hibernate/hibernate-orm · error · IllegalArgumentException
The id attribute is not declared on this type [{}]
Error message
The id attribute is not declared on this type [{}] What it means
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.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java:177
throw new IllegalArgumentException(
String.format(
"Attribute [%s#%s : %s] not castable to requested type [%s]",
getTypeName(),
attribute.getName(),
attribute.getType().getJavaType().getName(),
javaType.getName()
)
);
}
}
}
@Override
@Nonnull
public <Y> SqmSingularPersistentAttribute<J, Y> getDeclaredId(@Nonnull Class<Y> javaType) {
ensureNoIdClass();
if ( id == null ) {
throw new IllegalArgumentException( "The id attribute is not declared on this type [" + getTypeName() + "]" );
}
checkType( id, javaType );
@SuppressWarnings("unchecked") // safe, we just checked
final var castId = (SqmSingularPersistentAttribute<J, Y>) id;
return castId;
}
@Override
@Nonnull
public SimpleDomainType<?> getIdType() {
final var id = findIdAttribute();
if ( id != null ) {
return id.getType();
}
else {
final var idClassAttributes = getIdClassAttributesSafely();
if ( idClassAttributes != null ) {
if ( idClassAttributes.size() == 1 ) {View on GitHub (pinned to fad1729dce)
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
Example fix
// before var id = subtypeType.getDeclaredId(Long.class); // id lives on AbstractEntity -> throws // after var id = subtypeType.getId(Long.class); // walks supertype chain
Defensive patterns
Strategy: validation
Validate before calling
// Use hierarchy-aware lookup unless you truly need declared-only
SingularAttribute<? super E, ?> id = identifiableType.getId(javaType); // searches supertypes
// or check first:
if (identifiableType.getSupertype() instanceof IdentifiableType<?>) { /* id may be inherited */ } Try / catch
try {
return type.getDeclaredId(cls);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("not declared on this type")) {
return type.getId(cls); // fall back to inherited
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The version attribute is not declared by this type [{}]
- Mapped superclass '{}' may not specify an '@Inheritance' map
- Attribute '${attribute}' is declared as an '@Id' or '@Embedd
- Attribute '" + memberDetails.getName() + "' is declared by '
- {mappedSuperclassTypeName} is not a supertype of {componentT
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/9e9f02cb733a8d7b.
Report an issue: GitHub.