hibernate/hibernate-orm · error · IllegalArgumentException

Attribute [%s#%s : %s] not castable to requested type [%s]

Error message

Attribute [%s#%s : %s] not castable to requested type [%s]

What it means

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.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractIdentifiableType.java:159

	@Override
	public @Nullable SqmSingularPersistentAttribute<? super J, ?> findIdAttribute() {
		if ( id != null ) {
			return id;
		}
		else if ( getSuperType() != null ) {
			return getSuperType().findIdAttribute();
		}
		else {
			return null;
		}
	}

	private void checkType(SingularPersistentAttribute<?, ?> attribute, Class<?> javaType) {
		if ( !javaType.isAssignableFrom( attribute.getType().getJavaType() ) ) {
			if ( !( attribute.getAttributeJavaType() instanceof PrimitiveJavaType<?> primitiveJavaType )
					|| primitiveJavaType.getPrimitiveClass() != javaType ) {
				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() + "]" );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Pass the exact declared type: read id.getType().getJavaType() or use findIdAttribute() first and derive the type from the attribute instead of guessing
  2. Prefer the no-type lookups (findIdAttribute(), findVersionAttribute()) and cast after inspecting the Java type
  3. If refactoring changed the id type, update every getId(Class) call site — the message shows actual vs requested type

Example fix

// before
SingularAttribute<? super User, Long> id = userType.getId(Long.class); // id is actually String

// after
SingularAttribute<? super User, ?> idAttr = userType.getId(userType.getIdType().getJavaType());
// or: Class<?> idJavaType = userType.getIdType().getJavaType();
Defensive patterns

Strategy: validation

Validate before calling

// Derive the correct class from the metamodel instead of guessing
Class<?> actual = attribute.getType().getJavaType();
if (!requestedType.isAssignableFrom(actual)
        && actual != wrap(requestedType) /* primitive pair */) {
    throw new IllegalArgumentException("wrong type requested for " + attribute.getName());
}

Try / catch

try {
    return type.getId(expected);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("not castable to requested type")) {
        Class<?> real = type.getIdType().getJavaType();
        return type.getId((Class) real);
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


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