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

  1. Use getId(Class) instead — it resolves inherited ids via findIdAttribute() walking the supertype chain
  2. Keep the @Id on the concrete entity if you truly need getDeclaredId semantics
  3. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/9e9f02cb733a8d7b. Report an issue: GitHub.