Kotlin中使用CriteriaBuilder的isMember方法出现报错该如何解决
Kotlin 下 CriteriaBuilder.isMember 方法报错常见原因
- 泛型类型不匹配
Kotlin 的可空/非空类型校验、泛型约束比 Java 更严格,isMember方法要求传入的待校验元素类型,和集合属性的泛型类型完全一致。如果集合属性声明为非空类型,你传入了可空类型的变量,或者元素是集合泛型的子类,都会触发类型不匹配报错。你可以显式指定isMember的泛型参数,比如cb.isMember<String>(待校验元素, 集合路径),或者给待校验元素加非空断言,也可以通过.as(Path<目标类型>)对集合路径做显式类型转换对齐类型。 - 集合路径绑定错误
如果你的集合Path对象不是从当前查询的根实体正确关联获取的,比如查询根是Root<User>,但你传入的集合路径是从其他无关实体关联得到的,就会触发路径无效报错。请确认集合路径是从查询根实体出发,通过root.get("集合字段名")或者 JPA 元模型的属性引用正确获取。 - JPA 实现版本兼容缺陷
旧版本的 Hibernate、EclipseLink 等 JPA 实现对 Kotlin 的泛型推导支持不完善,尤其是 Hibernate 5.4 之前的版本,经常出现isMember泛型匹配失败的问题。你可以升级 JPA 实现到最新稳定版,也可以改用子查询的等价写法绕过该问题:
val subQuery = criteriaQuery.subquery(集合元素类型::class.java) val subRoot = subQuery.from(集合元素类型::class.java) subQuery.select(subRoot) .where( cb.equal(subRoot.get("关联父实体字段"), root.get("id")), cb.equal(subRoot.get("匹配字段"), 待校验元素) ) predicates.add(cb.exists(subQuery))
- 方法参数顺序错误
注意isMember方法的参数顺序是:第一个参数是待判断是否在集合里的元素,第二个参数是集合属性的Path对象,写反参数顺序也会直接触发类型不匹配报错。
内容的提问来源于stack exchange,提问作者Sebastian Garcia Fischer
相关产品推荐
相关产品推荐

