hibernate/hibernate-orm · error · SemanticException
Operand of 'member of' operator must be a plural path
Error message
Operand of 'member of' operator must be a plural path
What it means
isMember/isNotMember compile to an SQL MEMBER OF, which requires the collection operand to be a path to a plural attribute. createSqmMemberOfPredicate only accepts SqmPluralValuedSimplePath; passing any other expression (a literal, function result, subquery, joined entity, or singular attribute path) throws SemanticException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java:3315
@Nonnull
@Override
public <E, C extends Collection<E>> SqmPredicate isNotMember(@Nonnull Expression<E> elem, @Nonnull Expression<C> collection) {
return createSqmMemberOfPredicate( (SqmExpression<?>) elem, (SqmPath<?>) collection, true);
}
@Nonnull
@Override
public <E, C extends Collection<E>> SqmPredicate isNotMember(E elem, @Nonnull Expression<C> collection) {
return createSqmMemberOfPredicate( value( elem ), (SqmPath<?>) collection, true);
}
private SqmMemberOfPredicate createSqmMemberOfPredicate(SqmExpression<?> elem, SqmPath<?> collection, boolean negated) {
if ( collection instanceof SqmPluralValuedSimplePath<?> pluralValuedSimplePath ) {
return new SqmMemberOfPredicate( elem, pluralValuedSimplePath, negated, this );
}
else {
throw new SemanticException( "Operand of 'member of' operator must be a plural path" );
}
}
@Nonnull
@Override
public SqmPredicate like(@Nonnull Expression<String> searchString, @Nonnull Expression<String> pattern) {
return new SqmLikePredicate(
(SqmExpression<?>) searchString,
(SqmExpression<?>) pattern,
this
);
}
@Nonnull
@Override
public SqmPredicate like(@Nonnull Expression<String> searchString, @Nonnull String pattern) {
return new SqmLikePredicate(
(SqmExpression<?>) searchString,View on GitHub (pinned to fad1729dce)
Solutions
- Use the actual plural attribute path: cb.isMember(tag, root.get("tags")) or orderRoot.get("lineItems").
- For literal collections, use IN instead: cb.literal(value).in? no — use cb.in(...): path.in(values) or cb.isMember alternative cb.in(root.get("x")).value(...).
- If you joined through the entity side, switch to the collection side (order.get("items") rather than customer.join(...).get(...)).
Example fix
// before
Predicate p = cb.isMember(statusCode, root.get("customer")); // @ManyToOne -> SemanticException
// after
Predicate p = cb.isMember(statusCode, root.get("customer").get("accounts")); // @OneToMany path
// or for a plain value list use IN:
Predicate in = root.get("status").in(statusCodes); Defensive patterns
Strategy: type-guard
Validate before calling
boolean isPluralPath(Expression<?> collection) {
return collection instanceof Path<?> p
&& p.getModel() instanceof PluralAttribute<?, ?, ?>;
} Type guard
static boolean memberOfSupported(Expression<?> coll) {
return coll instanceof Path<?> p && p.getModel() instanceof PluralAttribute<?, ?, ?>;
} Try / catch
try {
p = cb.isMember(code, path);
} catch (SemanticException e) {
if (e.getMessage().contains("plural path")) { /* switch to path.in(values) or a real collection attribute */ }
else throw e;
} Prevention
- Use isMember only on @OneToMany/@ManyToMany/@ElementCollection paths.
- For literal collections use IN (path.in(list)), never isMember with a literal/subquery.
- Navigate to the owning side's collection attribute, not the inverse entity reference.
When it happens
Trigger: cb.isMember(code, root.get("order").get("customer")) where customer is @ManyToOne; cb.isMember(x, cb.literal(list)); cb.isMember(tag, subquery) or cb.isMember(tag, root.join("items")) — all are not plural-valued simple paths.
Common situations: Trying to express 'value is in this list' against a literal collection instead of using path.in(values); navigating to the wrong side of an association (entity side instead of the collection side); using the joined entity instead of the collection attribute in @OneToMany mappings.
Related errors
- Can't use expression '" + expression + " without explicit na
- Informix does not support binary literals
- No plural attribute named '{}' and of element type '{}' in t
- Given subclass table number is outside expected range [%s] a
- Not implemented yet
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/9487f71764be70a2.
Report an issue: GitHub.