私はJPAにかなり慣れていません.CriteriaBuilder/CriteriaQuery APIです:
オブジェクトのセットの抽出を照会したい (以下に示すように、結果の要素 n から m のみを選択する)
クエリ自体はうまく機能し、期待どおりの結果が得られます。
しかし、考えられる結果の全量を数えようとすると、java.lang.IllegalArgumentException が発生します。
org.hibernate.hql.internal.ast.QuerySyntaxException: 無効なパス: 'generatedAlias1.prop1' [com.myCompany.blablub.MyClass から count(generatedAlias0) を generatedAlias0 として選択 (1=1) および ( generatedAlias1.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();
私が間違っていることについてのヒントを教えていただければ幸いです。
私の問題がどこにあるかがわかると思います。
この動作は、結合を使用した場合にのみ表示されます。
結合なしのクエリは次のようになります。
select count(generatedAlias0) from MyClass as generatedAlias0 where ( 1=1 ) and ( generatedAlias0.blubb=:param0 )
しかし、結合を使用したい場合は、次のようになります。
select count(generatedAlias0) from MyClass as generatedAlias0 where ( 1=1 ) and ( generatedAlias1.blah=:param0 )
カウントなしのクエリは次のようになります。
select generatedAlias0 from MyClass as generatedAlias0 inner join generatedAlias0.prop1 as generatedAlias1 where ( 1=1 ) and ( generatedAlias1.blah=:param0 )
結合全体が欠落しているため、 generatedAlias1 が何であるかは明らかにわかりません。この動作を修正する方法を知っている人はいますか?