Can't compare test expression of type when upgrading to 6.2.0 or above from 6.1.7

Query code:

                CriteriaQuery<Video> criteria = cb.createQuery(Video.class);
                var root = criteria.from(Video.class);
                root.fetch("channel", JoinType.RIGHT);
                var subquery = criteria.subquery(User.class);
                var subroot = subquery.from(User.class);
                subquery.select(subroot.get("subscribed_ids"))
                        .where(cb.equal(subroot.get("id"), user.getId()));

                criteria.select(root)
                        .where(
                                root.get("channel").in(subquery)
                        )
                        .orderBy(cb.desc(root.get("uploaded")));

Stacktrace:

 java.lang.IllegalArgumentException: Can't compare test expression of type [Channel] with element of type [User]
 	at org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.assertComparable(SqmCriteriaNodeBuilder.java:2098)
 	at org.hibernate.query.sqm.tree.predicate.SqmInListPredicate.implyListElementType(SqmInListPredicate.java:138)
 	at org.hibernate.query.sqm.tree.predicate.SqmInListPredicate.<init>(SqmInListPredicate.java:60)
 	at org.hibernate.query.sqm.tree.predicate.SqmInListPredicate.<init>(SqmInListPredicate.java:47)
 	at org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.in(SqmCriteriaNodeBuilder.java:2618)
 	at org.hibernate.query.sqm.tree.expression.AbstractSqmExpression.in(AbstractSqmExpression.java:124)
 	at org.hibernate.query.sqm.tree.expression.AbstractSqmExpression.in(AbstractSqmExpression.java:31)
 	at me.kavin.piped.server.handlers.auth.FeedHandlers.feedResponse(FeedHandlers.java:119)

GH Link with line numbers: Piped-Backend/FeedHandlers.java at master · TeamPiped/Piped-Backend · GitHub

The code used to work on 6.1.7, has anything changed?

Sanity checks were added to help you find bugs in your code. Also see hibernate-orm/migration-guide.adoc at 6.2 · hibernate/hibernate-orm · GitHub

You have to use

var subquery = criteria.subquery(String.class);

and

root.get("channel").get("uploader_id").in(subquery)
1 Like

That was spot on, thank you!