hibernate/hibernate-orm · error · UnsupportedOperationException

Cannot access the type of plural valued simple paths

Error message

Cannot access the type of plural valued simple paths

What it means

The JPA TYPE operator returns the discriminator of an entity-valued path. A plural-valued path (the collection reference itself, as opposed to its elements) denotes many values and has no single discriminator, so SqmPluralValuedSimplePath.type() unconditionally throws UnsupportedOperationException. TYPE must be applied to an entity-valued path, typically the joined element of the collection.

Source

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

					SqmJoinType.INNER,
					false,
					nodeBuilder()
			);
			index = ( (SqmMapJoin<?, ?, ?>) join).key();
		}
		else {
			throw new NotIndexedCollectionException( "Index operator applied to path '" + getNavigablePath()
					+ "' which is not a list or map" );
		}
		join.setJoinPredicate( nodeBuilder().equal( index, selector ) );
		parent.addSqmJoin( join );
		return join;
	}

	@Nonnull
	@Override
	public SqmExpression<Class<? extends C>> type() {
		throw new UnsupportedOperationException( "Cannot access the type of plural valued simple paths" );
	}

	@Nonnull
	@Override
	public <S extends C> SqmTreatedPath<C, S> treatAs(@Nonnull Class<S> treatJavaType) {
		throw new UnsupportedOperationException( "Cannot treat plural valued simple paths" );
	}

	@Nonnull
	@Override
	public <S extends C> SqmTreatedEntityValuedSimplePath<C, S> treatAs(@Nonnull EntityDomainType<S> treatTarget) {
		throw new UnsupportedOperationException( "Cannot treat plural valued simple paths" );
	}

	@Nonnull
	@Override
	public SqmPredicate isEmpty() {
		return new SqmEmptinessPredicate( this, false, nodeBuilder() );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Join the collection and apply type() to the joined entity alias: 'select type(l) from Order o join o.lines l'
  2. Use element() to reference the collection contents before applying type(): 'type(element(o.lines))'
  3. For @ElementCollection of basic/embeddable values, TYPE has no meaning at all: select an explicit discriminator property instead

Example fix

// before
select o from Order o where type(o.lines) = SpecialLine

// after
select o from Order o join o.lines l where type(l) = SpecialLine
Defensive patterns

Strategy: type-guard

Validate before calling

if (path.getReferencedPathSource() instanceof org.hibernate.metamodel.model.domain.PluralPersistentAttribute<?, ?, ?>) {
    // apply type() to the joined element instead of this path
}

Type guard

static boolean isEntityTypePath(SqmPath<?> path) {
    return !(path.getReferencedPathSource()
        instanceof org.hibernate.metamodel.model.domain.PluralPersistentAttribute<?, ?, ?>);
}

Try / catch

try {
    expression = path.type();
} catch (UnsupportedOperationException e) {
    // plural path: join the collection and call type() on the join
}

Prevention

When it happens

Trigger: HQL 'select type(p.orders) from Person p' or 'where type(o.lines) = SpecialLine' where 'orders'/'lines' are @OneToMany/@ManyToMany; criteria code calling path.get("lines").type() or builder.type(...) on a plural path; any .type() call on a path whose referenced source is a PluralPersistentAttribute.

Common situations: Polymorphic collections where the developer wants the concrete class per element; copy-pasting a working type(o) expression from an entity path onto a collection path; discriminator filters ported from SQL CASE expressions.

Related errors


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