2015-01-14 6 views
0

를 사용하는 경우와 쿼리의 계산 결과는 내가 JPA에 오히려 새로운 오전이 CriteriaBuilder/CriteriaQuery의 API입니다 :: 절 ​​CriteriaQuery

당신이 아래에 볼 수있는 (객체 집합의 추출물을 조회 할

, 결과의 요소 n 만 선택)

쿼리 자체가 잘 작동하고 예상 한 결과를 얻습니다.

org.hibernate.hql.internal.ast.QuerySyntaxException : 잘못된 경로 'generatedAlias1 내가 가능한 결과의 전체 양을 계산하려고하면

는하지만, 난 java.lang.IllegalArgumentException를 얻을. prop1 '[generatedAlias0로 com.myCompany.blablub.MyClass에서 SELECT COUNT (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) 

분명히 전체 join이 없기 때문에 generatedAlias1이 무엇인지 알지 못합니다. 누구든지이 문제를 해결할 수있는 방법을 알고 있습니까?

답변

0

criteria 쿼리의 루트를 사용하여 조인을 만듭니다. countQuery의 루트를 사용하여 조인을 만들어야합니다.

Root<MyClass> countRoot = countQuery.from(MyClass.class); 
Join<MyClass, MyOtherClass> mycountJoin = countRoot.join(MyClass_.foo);