2013-05-11 2 views
1

CriteriaBuilder을 사용하여 쿼리를 생성하여 0보다 큰 주식이 모두 Product 인 것을 선택하려고합니다. 주식은 sum(DeliveryRow.amount) - sum(DispatchRow.amount)입니다. 두 코스 모두 오른쪽에만 들어 있습니다 Product.결과 Integer가있는 CriteriaBuilder 조인/하위 쿼리

나는 join()을 사용해야한다고 생각하지만 DeliveryRowDispatchRow 모두에 대해 Subquery을 만들려고했습니다. 이 쿼리에서

클래스

Product { 
    (...) 
} 

DeliveryRow { 
    @ManyToOne 
    private Product product; 

    private int amount; 
} 

DispatchRow { 
    @ManyToOne 
    private Product product; 

    private int amount; 
} 

쿼리

은 내가 xxx을 처리하는 방법을하지 확신합니다. 하위 쿼리를 만들려고했지만 그게 효과가 없습니다.

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Product> query = cb.createQuery(Product.class); 
Root product = query.from(Product.class); 
query.select(product); 

// sum of DeliveryRow.amount where DeliveryRow.product = Product 
// minus 
// sum of DispatchRow.amount where DispatchRow.product = Product 
Expression stock = xxx; 

query.where(cb.gt(stock, Integer.parseInt(0))); 
return em.createQuery(query).getResultList(); 

해결 방법에 대한 제안 사항이 있으십니까?

답변

0

저는 엔티티 검색을위한 세 가지 다른 접근법, NamedQueries, em.CreateQuery 및 CriteriaBuilder를 연구하면서 JPA/JPQL에 대한 연구를 최근 수행하고 있습니다. 내 생각에 CriteriaBuilder는 사용할 세 가지 중에서 가장 어색합니다. 이 상황을 처리하기 위해 NamedQuery를 만드는 것이 좋습니다. 구현 및 읽기가 훨씬 쉬울 것입니다.

SELECT p.name, SUM(delRow.amount) - SUM(disRow.amount) 
FROM Product p join p.deliveryRows delRow join p.dispatchRows disRow 
HAVING SUM(delRow.amount) - SUM(disRow.amount) > 0 

/* This assumes product has a Collection<DispatchRow> named dispatchRows 
    and a Collection<DeliveryRow> named deliveryRows. 
*/ 

//This should be concatenated or on one line 
@NamedQuery(name="Product.hasStock" 
    query="SELECT p.name, SUM(delRow.amount) - SUM(disRow.amount) 
    FROM Product p join p.deliveryRows delRow join p.dispatchRows disRow 
    HAVING SUM(delRow.amount) - SUM(disRow.amount) > 0"); 

다음이 실행은`제품 '기업에 대한 명명 된 쿼리 확인 :

이 0보다 큰 주식으로 모든 제품을 검색 할 수있는이 JPQL 식을 사용하여 EntityManager

@PersistenceContext 
EntityManager em; 

public void execute(){ 
    List<Object[]> products = 
     em.createNamedQuery("Product.hasStock").getResultList(); 

    /* Projections return a List<Object[]> where position 1 in the object array 
    corresponds with the first field in the select statement, position two 
    corresponds with the second field and so on... These can also be strongly typed 
    if an object is created and the constructor is specified in JPQL statement 
    */ 
} 

이 검색어는 diffe입니다. rent API를 사용하는 것보다 접근 할 수 있지만, JPQL 쿼리는 Criteria API보다 훨씬 뛰어나다. SQL과 매우 유사한 JPQL 구문과 비교할 때 API는 간결하고 직관적입니다. 이 경로를 결정한 경우 @NamedQueries을 보여주는 비디오 자습서를 작성하고 예측을 포함하는 쿼리 결과를 강력하게 입력하는 방법을 보여줍니다. 그것은 here 찾을 수 있습니다.

+0

타입 페치 때문에 CriteriaBuilder를 사용했지만 이전에 NamedQueries와 함께 작업 해 보았습니다. 걱정하지 않습니까? – Aquillo

+0

유형 안전성에 대한 관심사는 Object []입니까? –

+0

질의는 '문자열'이 아닙니다. 'DispatchRow'에 대한 변경 사항으로 인해 문제가 발생할 수 있습니까? – Aquillo