2012-04-30 10 views
3

이 JPA QL을 기준 작성 도구로 변환하려고합니다. JBoss 6.0.CriteriaBuilder를 사용할 때 컴파일 오류가 발생했습니다.

"SELECT ba FROM BankAccount ba WHERE ba.balance >= :amt ORDER BY ba.ownerName ASC" 

나는이 튜토리얼에 따라이 코드를 작성했습니다.

public List<BankAccount> findWithBalance(int amount) { 
    CriteriaBuilder cb = em.getCriteriaBuilder(); 
    CriteriaQuery<BankAccount> cq = cb.createQuery(BankAccount.class); 
    Root<BankAccount> from = cq.from(BankAccount.class); 

    ParameterExpression<Integer> balance = cb.parameter(Integer.class); 
    cq.select(from); 

    Predicate predicate = cb.gt(from.get("balance"), balance); 
    cq.where(predicate); 

    cq.orderBy(cb.asc(from.get("ownerName"))); 

    TypedQuery<BankAccount> query = em.createQuery(cq); 

    return query.getResultList(); 
} 

는하지만, 나는 라인에서 컴파일 오류가 점점 오전 :

Predicate predicate = cb.gt(from.get("balance"), balance); 

오류 :

The method gt(Expression<? extends Number>, Expression<? extends Number>) in the type CriteriaBuilder is not applicable for the arguments (Path<Object>, ParameterExpression<Integer>) 

답변

10

글쎄, 나는 마침내 gt() 메서드를 호출하는 올바른 방법을 발견했다. 다음은 완벽한 솔루션입니다. JBoss 6에서 완전하게 테스트되었습니다.

public List<BankAccount> findWithBalance(int amount) { 
    CriteriaBuilder cb = em.getCriteriaBuilder(); 
    CriteriaQuery<BankAccount> cq = cb.createQuery(BankAccount.class); 
    Root<BankAccount> from = cq.from(BankAccount.class); 

    ParameterExpression<Integer> balance = cb.parameter(Integer.class); 
    cq.select(from); 

    //Here is the trick! 
    Predicate predicate = cb.gt(from.<Integer> get("balance"), balance); 

    cq.where(predicate); 
    cq.orderBy(cb.asc(from.get("ownerName"))); 

    TypedQuery<BankAccount> query = em.createQuery(cq); 

    query.setParameter(balance, amount); 

    return query.getResultList(); 
} 
0

amountint 아닌 Expression 때문에 컴파일러는 불평 , 당신이 상수이고 그것을 사용하는 Expression을 만드는 법을 이해할 수 있는지 확인하십시오.

+0

수정 된 코드로 게시물을 편집하고 현재받는 오류 메시지를 제공 할 수 있습니까? ParameterExpression 인 arg를 사용하는 경우 같은 오류가 발생하는 것을 상상할 수 없습니다. 또한 그렇게하는 것은 아마도 당신이 원하는 것이 아닙니다. –

+0

코드와 새로운 오류 메시지가 업데이트되었습니다. 내가하고있는 일은 다양한 자습서에서 직접 나온 것이다. 기준 쿼리가 JBoss 6에서 수행 될 수 있다고 생각하지 않습니다. – RajV

3

JPA의 유형 안전 기능은 호환되지 않는 유형의 비교를 제한하므로 컴파일러 자체에서 오류가 발생합니다.

여기서 from.get("balance")Path<Object>을 반환하지만이 메서드는 java.lang.Number 유형의 매개 변수를 사용할 수 있으므로 오류가 발생합니다.

아래 코드를 시도해 볼 수 있습니다. 당신이 메타 모델 API를 사용하는 경우

//-- 
    Metamodel metamodel = em.getMetamodel(); 
    EntityType<BankAccount> pClass = metamodel.entity(BankAccount.class); 
    Predicate predicate = cb.gt(from.get(pClass.getSingularAttribute("balance", Integer.class)), balance); 
//-- 

, 당신은 디버깅 & 많은 청소기 쉽게하는 cb.gt(from.get(BankAccount_.balance), balance)로 ClassName_.field를 지정하여 직접 retieve 수 있습니다.

많은 엔티티가있는 경우 JPA 제공자가 수동으로 Metamodel 클래스를 작성하는 것이 어려울 수 있습니다.

+0

변경했습니다. 새 오류는 다음과 같습니다. CriteriaBuilder 유형의 gt (Expression , Expression ) 메서드는 인수에 사용할 수 없습니다 (SingularAttribute , ParameterExpression ) – RajV

+0

@RajV 컴파일 오류를 제거하기 위해 편집되었지만 테스트 할 수 없습니다. –

+0

답변을 게시했습니다. 상기 참조하십시오. – RajV

관련 문제