{"record":{"id":"9487f71764be70a2","repo":"hibernate/hibernate-orm","slug":"operand-of-member-of-operator-must-be-a-plural-p-9487f7","errorCode":null,"errorMessage":"Operand of 'member of' operator must be a plural path","messagePattern":"Operand of 'member of' operator must be a plural path","errorType":"exception","errorClass":"SemanticException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java","lineNumber":3315,"sourceCode":"\n\t@Nonnull\n\t@Override\n\tpublic <E, C extends Collection<E>> SqmPredicate isNotMember(@Nonnull Expression<E> elem, @Nonnull Expression<C> collection) {\n\t\treturn createSqmMemberOfPredicate( (SqmExpression<?>) elem, (SqmPath<?>) collection, true);\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <E, C extends Collection<E>> SqmPredicate isNotMember(E elem, @Nonnull Expression<C> collection) {\n\t\treturn createSqmMemberOfPredicate( value( elem ), (SqmPath<?>) collection, true);\n\t}\n\n\tprivate SqmMemberOfPredicate createSqmMemberOfPredicate(SqmExpression<?> elem, SqmPath<?> collection, boolean negated) {\n\t\tif ( collection instanceof SqmPluralValuedSimplePath<?> pluralValuedSimplePath ) {\n\t\t\treturn new SqmMemberOfPredicate( elem, pluralValuedSimplePath, negated, this );\n\t\t}\n\t\telse {\n\t\t\tthrow new SemanticException( \"Operand of 'member of' operator must be a plural path\" );\n\t\t}\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmPredicate like(@Nonnull Expression<String> searchString, @Nonnull Expression<String> pattern) {\n\t\treturn new SqmLikePredicate(\n\t\t\t\t(SqmExpression<?>) searchString,\n\t\t\t\t(SqmExpression<?>) pattern,\n\t\t\t\tthis\n\t\t);\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmPredicate like(@Nonnull Expression<String> searchString, @Nonnull String pattern) {\n\t\treturn new SqmLikePredicate(\n\t\t\t\t(SqmExpression<?>) searchString,","sourceCodeStart":3297,"sourceCodeEnd":3333,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java#L3297-L3333","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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(...))."],"exampleFix":"// before\nPredicate p = cb.isMember(statusCode, root.get(\"customer\")); // @ManyToOne -> SemanticException\n\n// after\nPredicate p = cb.isMember(statusCode, root.get(\"customer\").get(\"accounts\")); // @OneToMany path\n// or for a plain value list use IN:\nPredicate in = root.get(\"status\").in(statusCodes);","handlingStrategy":"type-guard","validationCode":"boolean isPluralPath(Expression<?> collection) {\n    return collection instanceof Path<?> p\n            && p.getModel() instanceof PluralAttribute<?, ?, ?>;\n}","typeGuard":"static boolean memberOfSupported(Expression<?> coll) {\n    return coll instanceof Path<?> p && p.getModel() instanceof PluralAttribute<?, ?, ?>;\n}","tryCatchPattern":"try {\n    p = cb.isMember(code, path);\n} catch (SemanticException e) {\n    if (e.getMessage().contains(\"plural path\")) { /* switch to path.in(values) or a real collection attribute */ }\n    else throw e;\n}","preventionTips":["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."],"tags":["hibernate","criteria","member-of","plural-attribute","semantic"],"backgroundTag":"member-of-non-collection","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}