hibernate/hibernate-orm · error · UnsupportedOperationException
isNotMember() is not supported for SqmSubQuery
Error message
isNotMember() is not supported for SqmSubQuery
What it means
JpaExpression inherits isNotMember(Expression<Collection>) but a subquery is a query node, not an element that can be tested for collection membership, so SqmSubQuery implements it to always throw UnsupportedOperationException. The negated membership predicate must be built with CriteriaBuilder.isNotMember(element, collection), which accepts any expression, including a subquery.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/select/SqmSubQuery.java:775
return nodeBuilder().selectCase( this );
}
@Nonnull
@Override
public <R> SqmCaseSimple<T, R> selectCase(@Nonnull Class<R> resultType) {
return nodeBuilder().selectCase( this, resultType );
}
@Nonnull
@Override
public SqmPredicate isMember(@Nonnull Expression<? extends Collection<? super T>> collection) {
throw new UnsupportedOperationException( "isMember() is not supported for SqmSubQuery" );
}
@Nonnull
@Override
public JpaPredicate isNotMember(@Nonnull Expression<? extends Collection<? super T>> collection) {
throw new UnsupportedOperationException( "isNotMember() is not supported for SqmSubQuery" );
}
@Nonnull
@Override
public SqmNumericExpression<Long> count() {
return new SqmNumericExpressionWrapper<>( nodeBuilder().count( this ) );
}
@Nonnull
@Override
public SqmNumericExpression<Long> countDistinct() {
return new SqmNumericExpressionWrapper<>( nodeBuilder().countDistinct( this ) );
}
@Override
public @Nullable SqmBindableType<T> getNodeType() {
return expressibleType;
}View on GitHub (pinned to fad1729dce)
Solutions
- Create the predicate via the builder: cb.isNotMember(subquery, collectionPath)
- In generic code, branch on 'expression instanceof JpaSubQuery' before invoking expression-level membership methods
- For 'value NOT IN (subquery)' semantics, use cb.in(...).value(subquery).not() instead
Example fix
// before
Subquery<Long> sub = query.subquery(Long.class);
Predicate p = sub.isNotMember(orderRoot.get("tags")); // UnsupportedOperationException
// after
Predicate p = cb.isNotMember(sub, orderRoot.get("tags")); Defensive patterns
Strategy: type-guard
Validate before calling
if (expr instanceof JpaSubQuery<?>) { p = cb.isNotMember(expr, collection); } else { p = expr.isNotMember(collection); } Type guard
static Predicate notMemberOf(CriteriaBuilder cb, Expression<?> elem, Expression<? extends Collection<?>> coll) { return cb.isNotMember(elem, coll); } Try / catch
try { p = expr.isNotMember(coll); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("isNotMember")) p = cb.isNotMember(expr, coll); else throw e; } Prevention
- Route all membership predicates through the builder so expression kind never matters
- Keep a shared helper for membership/negation instead of calling expression methods inline
- Test predicate factories with subquery-valued elements
When it happens
Trigger: Calling subquery.isNotMember(collectionExpression) — typically from generic predicate factories that uniformly call isNotMember on Expression<T> when T matches the collection element type.
Common situations: Specification/filter DSLs that dispatch on expression type; negated membership checks generated reflectively; code migrated from literal- or path-based expressions where the call worked.
Related errors
- isMember() is not supported for SqmSubQuery
- DELETE query cannot be sub-query
- Not correlated
- The JPA specification does not support subqueries in the fro
- Correlated derived root does not have an entity type. Use ge
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/5c94b6dab3a2bca6.
Report an issue: GitHub.