Criteria isMember() doesn't work with collections mapped as array

Description

Given the following entity:

public class EntityWithArray { ... @Column(name = "labels") private Set<String> labels = new HashSet<>();

I would expect that CriteriaBuilder#isMember() would work:

var cb = em.getCriteriaBuilder(); var cq = cb.createQuery(EntityWithArray.class); var root = cq.from(EntityWithArray.class); cq.where(cb.isMember("label", root.get("labels")));

However, this fails with an exception:

org.hibernate.query.SemanticException: Operand of 'member of' operator must be a plural path at org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.createSqmMemberOfPredicate(SqmCriteriaNodeBuilder.java:2725) at org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.isMember(SqmCriteriaNodeBuilder.java:2707)

Reproducer: https://github.com/hibernate/hibernate-orm/pull/9918

Activity

Show:

Christian Beikov 4 days ago

Look at the method signatures of the CriteriaBuilder.In type, this wouldn’t work unless you do unchecked casts.

I can imagine supporting collections for the isMember/isNotMember methods, because the Java generics would work out, but arrays wouldn’t work without unsafe casts.

Overall, I think it’s simply better to rely on the dedicated methods arrayContains()/collectionContains(). With respect to bugs related to enum collections, lets discuss that on https://hibernate.atlassian.net/browse/HHH-19294.

Pavel Hrabec 4 days ago

Is this behavior something that is expected in the longer term? From the user PoV it is a bit confusing that a collection mapped using @ElementCollection is supported by isMember() but a collection mapped as an array is not.

Anyway, I’ve encountered another issue affecting the usage of array/collectionContains() with enums: https://hibernate.atlassian.net/browse/HHH-19294

Christian Beikov 4 days ago

To check if an expression is contained in an array, you have to use HibernateCriteriaBuilder.arrayContains(). In HQL we have syntax sugar that allows to use where 'label' in e.labels, but that is just for HQL. Also see https://in.relation.to/2024/08/08/orm-660/#array-syntax-sugar and https://docs.jboss.org/hibernate/orm/6.6/userguide/html_single/Hibernate_User_Guide.html#hql-array-contains-functions

Gavin King 4 days ago

I don’t think this is supposed to work. I think you’re supposed to use HibernateCriteriaBuilder.in(). Is that correct, ?

Rejected

Details

Assignee

Reporter

Affects versions

Priority

Created 4 days ago
Updated 4 days ago
Resolved 4 days ago