hibernate/hibernate-orm · error · IllegalArgumentException

Passed attribute name [%s] did not correspond to a collectio

Error message

Passed attribute name [%s] did not correspond to a collection (map) reference [%s] relative to %s

What it means

AbstractSqmFrom.joinMap(attributeName, joinType) requires the resolved attribute to be a MapPersistentAttribute (java.util.Map mapping with key/value semantics). Any other plural or singular kind throws IllegalArgumentException naming the attribute, the resolved source and the navigable path.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/AbstractSqmFrom.java:637

	}

	@Nonnull
	@Override
	@SuppressWarnings("unchecked")
	public <K, V> SqmMapJoin<T, K, V> joinMap(@Nonnull String attributeName, @Nonnull JoinType jt) {
		final var joinedPathSource = getReferencedPathSource().getSubPathSource( attributeName );

		if ( joinedPathSource instanceof MapPersistentAttribute<?, ?, ?> ) {
			final var join = buildMapJoin(
					(MapPersistentAttribute<T, K, V>) joinedPathSource,
					SqmJoinType.from( jt ),
					false
			);
			addSqmJoin( join );
			return join;
		}

		throw new IllegalArgumentException(
				String.format(
						Locale.ROOT,
						"Passed attribute name [%s] did not correspond to a collection (map) reference [%s] relative to %s",
						attributeName,
						joinedPathSource,
						getNavigablePath()
				)
		);
	}

	@Nonnull
	@Override
	public <R> SqmEntityJoin<T, R> join(@Nonnull Class<R> entityJavaType) {
		return join( nodeBuilder().getDomainModel().entity( entityJavaType ) );
	}

	@Nonnull
	@Override

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use joinCollection/joinSet/joinList/join matching the actual container type.
  2. Use the typed overload join(MapAttribute) from the metamodel for compile-time safety.
  3. Check the metamodel attribute kind before choosing the method.

Example fix

// before
productRoot.joinMap( "specs", JoinType.LEFT ); // specs is List<Spec>
// after
productRoot.joinList( "specs", JoinType.LEFT );
Defensive patterns

Strategy: type-guard

Type guard

static boolean isMap(ManagedType<?> type, String attr) {
    return type.getAttribute( attr ) instanceof jakarta.persistence.metamodel.MapAttribute;
}

Prevention

When it happens

Trigger: root.joinMap("translations", JoinType.INNER) when translations is Collection/List/Set; joinMap on a @ManyToOne or basic attribute.

Common situations: Changing a Map field to a List during refactoring; generic code assuming map semantics; keys modeled via @MapKey and then the field changed to a collection type.

Related errors


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