我试图编写一个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
。
那么代码出了什么问题?
答案 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));
我搞砸了这个的原因是因为我的应用程序中的函数也有一个变量,表明无论何时需要true
或false
。我做了一个if-else语句,所以我根据这个变量返回cb.greaterThan
或cb.lessThanOrEqualTo
。