greaterThan 查询在 > 附近抛出意外的 AST 节点

greaterThan query throws unexpected AST node near >

我正在尝试编写一个谓词,其中只有 class 员工的对象在拥有超过 1 个经理时才被 return 编辑。当该员工有超过 1 名经理时,它应该 return true,如果有 0 或 1,则应该 false。总结果应该针对指示过滤器选项的布尔值进行断言用户已选择,但为了简单起见,我将最后一行中的变量替换为硬编码值 true。代码如下所示:

public Predicate toPredicate(final Root<Employee> employeeRoot, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
    final Subquery<Long> subquery = query.subquery(Long.class);
    final Root<EmployeeManager> employeeManagerRoot = subquery.from(EmployeeManager.class);
    subquery.select(cb.count(employeeManagerRoot));
    subquery.where(cb.equal(employeeManagerRoot.get("employee"), employeeRoot.<Long> get("id")));

    return cb.equal(cb.greaterThan(subquery, Long.valueOf(1)), true);
}

但是,尝试 运行 此代码时会产生以下错误:

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: > near line 1, column 453 [select generatedAlias0 from com.test.domain.core.entities.Employee as generatedAlias0 where ( generatedAlias0.id in (select generatedAlias1.employee.id from com.test.domain.core.entities.EmployeeManager as generatedAlias1 where generatedAlias1.manager=1L) ) and ( (select count(generatedAlias2) from com.test.domain.core.entities.EmployeeManager as generatedAlias2 where generatedAlias2.employee=generatedAlias0.id)>1L=:param0 )

我试过运行将异常中输出的SQL直接输入到数据库中,似乎return输入了正确的值!但是,如您所见,我正在尝试确认 greaterThan 函数是否等于 true。正如您在异常消息中看到的那样,此 true 已替换为 :param0

那么代码中出了什么问题?

看起来您不需要子查询,只需一个 GROUP BY - HAVING 语句,如下所示。使用 EclipseLink 测试:

CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<Employee> root = cq.from(Employee.class);
Join<Employee, Manager> managers = root.join("managers");
Expression<Long> countManagers = cb.count(managers);
cq.multiselect(root, countManagers);
cq.groupBy(root);
cq.having(cb.greaterThan(countManagers, Long.valueOf(1)));
List<Tuple> result = em.createQuery(cq).getResultList();
for (Tuple t : result) {
    Employee emp = (Employee) t.get(0);
}

原来问题出在最后一行。无需检查 greaterThan 函数是否等于 true。

return cb.equal(cb.greaterThan(subquery, Long.valueOf(1)), true);

更改为

return cb.greaterThan(subquery, Long.valueOf(1));

我把这个搞砸的原因是因为我的应用程序中的函数还有一个变量,指示何时需要 truefalse。我做了一个 if-else 语句,所以我 return cb.greaterThancb.lessThanOrEqualTo 取决于这个变量。