2011-04-05 3 views
0

HQL에서 완전히 작동하는 쿼리가 있습니다. 그러나, 나는 그것을 읽기 쉽고 유지하기 쉬운 Criteria 폼으로 표현하고 싶습니다.HQL을 기준으로 변환

이것은 시나리오입니다. 저는 노동자, 사람 및 지불금이 있습니다. 작업자는 Person plus a Job Type입니다 (이 애플리케이션에서 한 사람은 동시에 다른 작업 유형을 가진 두 명의 작업자가 될 수 있음). 많은 지불이 있고, 1 명의 노동자를 위해 2 개 이상 있을지도 모르다. 나는 각 근로자에게 한 번씩, 그리고 그 노동자에 대한 모든 지불 가치의 합계를 구해야한다. 하나 하나가 내가 그 노동자를 위해이 방법을 지불의 합계를 얻기 위해 (이 지불이며,

Payment.findAll("from Payment as p where p.month = :m and p.year = :y group by p.worker.id, p.worker.person.id", [m: paymentsMonth, y: paymentsYear]) 

2 - 지불을 통해 반복하는 :

1- 모든 지불을 얻기 : 다음은 HQL 쿼리입니다) :

def totalLiquidValue = Payment.executeQuery('''select sum(liquidValue) from Payment where 
               month = :m and 
               year = :ar and 
               worker = :w''', 
               [m: it.paymentMonth, ar: it.year, w: payment.worker]) 
               .first() 

그것은 작동하지만 내가 쓸 시도하지 기준이 그것을 대체 :

1

,
def payments = Payment.withCriteria { 
        worker { 

         projections { 
          groupProperty('jobType') 
         } 

         person { 
          projections { 
           groupProperty('id') 
          } 
         } 
        } 

        eq('month', paymentsMonth) 
        eq('year', paymentsYear) 
       } 

그것은 실패 :

'MSID'실제로 'ID'의 이름입니다 "com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException 알 수없는 열이 '필드 목록'에서 'person_ali2_.msid'" 필드에 표시됩니다. 도메인 클래스 Worker에서 ID를 매핑하면됩니다.

새로운 가능성이 있습니까?

감사

업데이트 :

우리는 클라이언트가 제공 한 기존 데이터베이스를 사용할 필요가있다. 더 나은 조직을 위해 우리가 사용하는 클래스는 "legacy_tablename"이라는 이름의 뷰로 표현되며 시스템의 내부에만있는 모든 것이 별도의 데이터베이스에 있으므로보기가 다른 데이터베이스의 테이블을 참조하므로 코드 내에서 여러 데이터베이스를 처리해야합니다. 그래서 때때로 테이블 이름이 지정되는 이유입니다. ,

class Payment{ 

    Integer year 
    Integer month 

    Worker worker 

    BigDecimal liquidValue 

} 

class Worker { 
    Person person 
    Integer jobType 

    static mapping = { 
     table("legacy_worker") 
     id(composite: ["jobType", "person"]) 
     person(column: "msid", fetch: "join") 
    }  
} 

class Person { 
    String id 

    static mapping = { 
     table("legacy_person") 
     id(column:"msid", generator: "assigned") 
    } 
} 

감사

+0

결제 방법 * * 및 p.month = : m은 HQL에서 작동합니까? –

+0

Payment, Worker 및 Person의 도메인 개체를 제공 할 수 있습니까? 이것은 우리 모두가 세부 사항을 더 잘 이해하는 데 도움이 될 것입니다. –

+0

폴라 노, 미안. 코드는 영어가 아니므로 여기에 넣은 다음 변수 이름을 번역합니다.이 '와'는 오타였습니다. – Gabriel

답변

0
 def payments = Payment.withCriteria { 
      createAlias('worker','w') 
      projections { 
       property('w.id') 
       groupProperty('w.jobType') 
       groupProperty('w.person')      
      } 
      eq('month', paymentsMonth) 
      eq('year', paymentsYear) 
     } 
쿼리 당신에게 첫번째 요소는 노동자가 될 것입니다 목록의 목록을 줄 것이다 위

:

도메인 클래스는 큰하지만이 그들에 대해 중요한 사항입니다 2 번째는 jobType이고 3 번째는 달과 해를 부여한 person 객체입니다.

def payments = Payment.withCriteria { 
      projections { 
      sum('liquidValue') 
      } 
      eq('month', paymentsMonth) 
      eq('year', paymentsYear) 
      eq('worker',worker) 
     } 
+0

감사합니다. 이것이 내적 예측을위한 표기법이라는 것을 알지 못했습니다. 그러나 이상하게도 질의는 정수리스트를 반환하는데, 이것은 Workers의 jobTypes입니다. 속성 ('작업자') 투영을 추가하려고했지만 작업자가 단일 열에 매핑되지 않는다는 것을 알리는 것은 실패합니다. – Gabriel

+0

답변을 업데이트하여 작업자 개체를 첫 번째 쿼리에서 반환했습니다. 그게 효과가 있기를 바래요? –

+0

아쉽게도 "org.hibernate.QueryException : 속성이 속성 : 'worker'의 단일 열 : worker로 매핑되지 않습니다. Grails가이 관계에서 작성된 ID (Worker에서)를 올바르게 처리하지 않기 때문이라고 생각합니다. – Gabriel

관련 문제