[英]In JPA: counting results of query with where clause using CriteriaQuery
I am rather new to JPA and it's CriteriaBuilder / CriteriaQuery API: 对于JPA来说,我不是一个新手,它是CriteriaBuilder / CriteriaQuery API:
I want to query an extract of a set of Objects(as you can see below, i only select element n to m of the results) 我想查询一组对象的摘录(如您在下面看到的,我仅选择结果的元素n至m)
The query itsself works well and I get the results i expect. 该查询本身运行良好,我得到了我期望的结果。
But if i try to count the whole amount of possible results, i get a java.lang.IllegalArgumentException: 但是,如果我尝试计算所有可能的结果,则会得到java.lang.IllegalArgumentException:
org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.prop1' [select count(generatedAlias0) from com.myCompany.blablub.MyClass as generatedAlias0 where ( 1=1 ) and ( generatedAlias1.prop1=:param0 )]"
org.hibernate.hql.internal.ast.QuerySyntaxException:无效路径:“ generatedAlias1.prop1” [从com.myCompany.blablub.MyClass中选择count(generatedAlias0)作为generateAlias0,其中(1 = 1)和(generateAlias1.prop1 =:param0 )]”
final CriteriaQuery<MyClass> criteriaQuery = builder.createQuery(MyClass.class);
CriteriaQuery<Long> countQuery = builder.createQuery(Long.class);
countQuery.select(builder.count(countQuery.from(MyClass.class)));
Long totalCount = -1L;
List<MyClass> MyClassList;
Root<MyClass> root = criteriaQuery.from(MyClass.class);
if(myClassFilter != null) {
List<Predicate> predicates = new ArrayList<Predicate>();
if(myClassFilter.getProp1() != null) {
Join<MyClass, MyOtherClass> myJoin1 = root.join(MyClass_.prop1);
predicates.add(builder.equal(myJoin1.get(MyOtherClass_.blah), myClassFilter.getProp1() ));
}
if(myClassFilter.getProp2() != null) {
predicates.add(builder.equal(root.get(MyClass_.blubb), myClassFilter.getProp2() ));
}
if(myClassFilter.getProp3() != null) {
Join<MyClass, MyOtherClass> myJoin2 = root.join(MyClass_.foo);
predicates.add(builder.equal(myJoin2.get(MyOtherClass_.bar), myClassFilter.getProp3() ));
}
if (myClassFilter.getSpecialPropList() != null) {
if (myClassFilter.getSpecialPropList().length>0) {
Predicate orPredicates = builder.disjunction();
for (String specialProp : myClassFilter.getSpecialPropList()) {
Join<MyClass, specialProp> specialPropJoin = root.join(MyClass_.specialProps);
Predicate newPredicate = builder.equal(specialPropJoin.get(specialProp_.dudum), specialProp);
orPredicates = builder.or(orPredicates, newPredicate);
}
predicates.add(orPredicates);
}
}
Predicate finalPredicate = builder.conjunction();
for(Predicate p: predicates) {
finalPredicate = builder.and(finalPredicate, p);
}
criteriaQuery.select(root).where(finalPredicate);
countQuery.where(finalPredicate);
}
count = entityManager.createQuery(countQuery).getFirstResult();
TypedQuery<MyClass> typedQuery = entityManager.createQuery(criteriaQuery);
if(first >= 0) {
typedQuery.setFirstResult(first);
}
if(count > 0) {
typedQuery.setMaxResults(count);
}
MyClassList = typedQuery.getResultList();
I hope you can give me a hint on what im doing wrong. 希望您能给我一个提示,指出我做错了什么。
I think i see where my problem is. 我想我知道我的问题在哪里。
The behaviour only apprears when i use a join. 仅当我使用联接时,该行为才发生。
a query without join looks like this: 没有连接的查询如下所示:
select count(generatedAlias0) from MyClass as generatedAlias0 where ( 1=1 ) and ( generatedAlias0.blubb=:param0 )
but when i want to use a join it looks like this: 但是当我想使用联接时,它看起来像这样:
select count(generatedAlias0) from MyClass as generatedAlias0 where ( 1=1 ) and ( generatedAlias1.blah=:param0 )
while the query without count looks like this: 而没有计数的查询看起来像这样:
select generatedAlias0 from MyClass as generatedAlias0 inner join generatedAlias0.prop1 as generatedAlias1 where ( 1=1 ) and ( generatedAlias1.blah=:param0 )
it obviously doesnt know what generatedAlias1 is because the whole join is missing. 它显然不知道什么是generateAlias1,因为缺少整个联接。 does anyone know how i can fix this behaviour?
有谁知道我该如何解决这个问题?
You create a join using the root of the criteriaQUery. 您可以使用criteriaQUery的根创建联接。 You need to create a join using the root of your countQuery as well.
您还需要使用countQuery的根创建连接。
Root<MyClass> countRoot = countQuery.from(MyClass.class);
Join<MyClass, MyOtherClass> mycountJoin = countRoot.join(MyClass_.foo);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.