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));
我把这个搞砸的原因是因为我的应用程序中的函数还有一个变量,指示何时需要 true
或 false
。我做了一个 if-else 语句,所以我 return cb.greaterThan
或 cb.lessThanOrEqualTo
取决于这个变量。
我正在尝试编写一个谓词,其中只有 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));
我把这个搞砸的原因是因为我的应用程序中的函数还有一个变量,指示何时需要 true
或 false
。我做了一个 if-else 语句,所以我 return cb.greaterThan
或 cb.lessThanOrEqualTo
取决于这个变量。