hibernate/hibernate-orm · error · IllegalArgumentException

MapAttribute named ${name} does not support a key of type ${

Error message

MapAttribute named ${name} does not support a key of type ${keyType}

What it means

The typed map lookup getMap(name, keyType, valueType) passed the value-type check but failed the key check: mapAttribute.getKeyJavaType() != keyType uses strict Class identity (not assignability). The requested key Class must be exactly the map's declared key type.

Source

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

	@Nonnull
	public <K, V> MapAttribute<? super J, K, V> getMap(
			@Nonnull String name,
			@Nonnull Class<K> keyType,
			@Nonnull Class<V> valueType) {
		final var attribute = findPluralAttribute( name );
		checkMapValueType( attribute, name, valueType );
		final var mapAttribute = (MapAttribute<? super J, K, V>) attribute;
		checkMapKeyType( mapAttribute, name, keyType );
		return mapAttribute;
	}

	private <V> void checkMapValueType(PluralAttribute<? super J, ?, ?> attribute, String name, Class<V> valueType) {
		checkTypeForPluralAttributes( "MapAttribute", attribute, name, valueType, PluralAttribute.CollectionType.MAP);
	}

	private <K,V> void checkMapKeyType(MapAttribute<? super J, K, V> mapAttribute, String name, Class<K> keyType) {
		if ( mapAttribute.getKeyJavaType() != keyType ) {
			throw new IllegalArgumentException( "MapAttribute named " + name + " does not support a key of type " + keyType );
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	@Nonnull
	public <K, V> MapAttribute<J, K, V> getDeclaredMap(
			@Nonnull String name,
			@Nonnull Class<K> keyType,
			@Nonnull Class<V> valueType) {
		final var attribute = findDeclaredPluralAttribute( name );
		checkMapValueType( attribute, name, valueType );
		final var mapAttribute = (MapAttribute<J, K, V>) attribute;
		checkMapKeyType( mapAttribute, name, keyType );
		return mapAttribute;
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Pass the exact key type: inspect mapAttribute.getKeyJavaType() (via findPluralAttribute first) and request that class
  2. Use the untyped getMap(name) overload which skips key/value type checks
  3. Avoid widening key types in generic helpers; branch on the real key class

Example fix

// before
MapAttribute<Config, Object, String> m = configType.getMap("labels", Object.class, String.class); // key is String -> throws

// after
MapAttribute<Config, String, String> m = configType.getMap("labels", String.class, String.class);
Defensive patterns

Strategy: validation

Validate before calling

// Resolve the exact key class first; the check is Class identity (==)
var any = type.findPluralAttribute(name);
if (any instanceof javax.persistence.metamodel.MapAttribute<?,?,?> m
        && m.getKeyJavaType() == keyType) {
    return type.getMap(name, keyType, valueType);
}
throw new IllegalArgumentException(
    name + " key type is " + (any == null ? "?" : ((MapAttribute<?,?,?>) any).getKeyJavaType()));

Try / catch

try {
    return type.getMap(name, keyType, valueType);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("does not support a key of type")) {
        Class<?> realKey = type.getMap(name).getKeyJavaType();
        return type.getMap(name, (Class) realKey, valueType);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling getMap("labels", Object.class, String.class) on Map<String,String>; passing a subclass (e.g. Long.class for a key actually typed as the declared Long works, but Integer vs int, or String vs CharSequence fails); primitive/wrapper mismatches in the key.

Common situations: Generic code passing Object.class or a widened type as the key; keys whose declared type is a primitive wrapper and the caller passes the primitive class; map keys changed during refactoring.

Related errors


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