greaterThan查询在>

时间:2016-04-19 14:21:42

标签: java jpa hql jpql criteria-api

我试图编写一个Predicate,当只有一个Manager时,只返回Employee类的对象。如果此员工的管理员数超过1,则应返回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);
}

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

  

引起:org.hibernate.hql.internal.ast.QuerySyntaxException:   意外的AST节点:&gt;靠近第1行,第453列[select generatedAlias0   从com.test.domain.core.entities.Employee作为generatedAlias0其中(   generatedAlias0.id in(select generatedAlias1.employee.id from   com.test.domain.core.entities.EmployeeManager as generatedAlias1 where   generatedAlias1.manager = 1L))和((select count(generatedAlias2)   从com.test.domain.core.entities.EmployeeManager作为generatedAlias2   其中generatedAlias2.employee = generatedAlias0.id)&gt; 1L =:param0)

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

那么代码出了什么问题?

2 个答案:

答案 0 :(得分:0)

看起来你不需要子查询,只需要一个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);
}

答案 1 :(得分:0)

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

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

更改为

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

我搞砸了这个的原因是因为我的应用程序中的函数也有一个变量,表明无论何时需要truefalse。我做了一个if-else语句,所以我根据这个变量返回cb.greaterThancb.lessThanOrEqualTo