2012-04-13 10 views
8

Mam pytanie dotyczące kryteriów JPA.Kryterium zapytania JPA Path.get left join jest to możliwe

Oto moje kryteria JPA zapytania:

CriteriaBuilder criteriaBuilder = getEm().getCriteriaBuilder(); 
CriteriaQuery<InventoryItemSumReport> query = criteriaBuilder.createQuery(InventoryItemSumReport.class); 
Root<InventoryItemDetail> from = query.from(InventoryItemDetail.class);  

Join<InventoryItemDetail, InventoryItem> joinItem = from.join(InventoryItemDetail_.inventoryItem); 

Predicate where = criteriaBuilder.lessThanOrEqualTo(from.get(InventoryItemDetail_.effectiveDate), date); 

query.multiselect(joinItem.get(InventoryItem_.product),joinItem.get(InventoryItem_.facility),joinItem.get(InventoryItem_.customer)); 
query.groupBy(joinItem.get(InventoryItem_.product),joinItem.get(InventoryItem_.facility),joinItem.get(InventoryItem_.customer)); 
query.where(where); 

TypedQuery<InventoryItemSumReport> createQuery = getEm().createQuery(query);  
List<InventoryItemSumReport> resultList = createQuery.getResultList(); 

Oto wynikające zapytania produkowane przez dostawcę JPA:

select 
     inventoryi1_.PRODUCT_ID as col_0_0_, 
     inventoryi1_.FACILITY_ID as col_1_0_, 
     inventoryi1_.CUSTOMER_ID as col_2_0_ 
    from 
     INVENTORY_ITEM_DETAIL inventoryi0_ 
    inner join 
     INVENTORY_ITEM inventoryi1_ 
      on inventoryi0_.INVENTORY_ITEM_ID=inventoryi1_.ID 
    inner join 
     PRODUCT product2_ 
      on inventoryi1_.PRODUCT_ID=product2_.ID 
    inner join 
     FACILITY facility3_ 
      on inventoryi1_.FACILITY_ID=facility3_.ID 
    inner join 
     CUSTOMER customer4_ 
      on inventoryi1_.CUSTOMER_ID=customer4_.ID 
    where 
     inventoryi0_.EFFECTIVE_DATE<= ? 
    group by 
     inventoryi1_.PRODUCT_ID , 
     inventoryi1_.FACILITY_ID , 
     inventoryi1_.CUSTOMER_ID 

Ale chciałbym następujące zapytanie:

select 
     inventoryi1_.PRODUCT_ID as col_0_0_, 
     inventoryi1_.FACILITY_ID as col_1_0_, 
     inventoryi1_.CUSTOMER_ID as col_2_0_ 
    from 
     INVENTORY_ITEM_DETAIL inventoryi0_ 
    inner join 
     INVENTORY_ITEM inventoryi1_ 
      on inventoryi0_.INVENTORY_ITEM_ID=inventoryi1_.ID 
    inner join 
     PRODUCT product2_ 
      on inventoryi1_.PRODUCT_ID=product2_.ID 
    inner join 
     FACILITY facility3_ 
      on inventoryi1_.FACILITY_ID=facility3_.ID 
    left join 
     CUSTOMER customer4_ 
      on inventoryi1_.CUSTOMER_ID=customer4_.ID 
    where 
     inventoryi0_.EFFECTIVE_DATE<= ? 
    group by 
     inventoryi1_.PRODUCT_ID , 
     inventoryi1_.FACILITY_ID , 
     inventoryi1_.CUSTOMER_ID 

z left join CUSTOMER, aby uzyskać wyniki gdzie Customers są puste.
Customer, Product, Facility są wszystkie obiekty, natomiast InventoryItemSumReport jest obiektem o wartości lub DTO.

public class InventoryItemSumReport implements Serializable { 

    private static final long serialVersionUID = 1L; 

    private Product product; 
    private Facility facility; 
    private Customer customer; 

    public InventoryItemSumReport(Product product, Facility facility, Customer customer) { 
     super(); 
     this.product = product; 
     this.facility = facility; 
     this.customer = customer; 
    } 
} 

Odpowiedz

8

znalazłem następujący sposób to działa:

CriteriaBuilder criteriaBuilder = getEm().getCriteriaBuilder(); 
CriteriaQuery<InventoryItemSumReport> query = criteriaBuilder.createQuery(InventoryItemSumReport.class); 
Root<InventoryItemDetail> from = query.from(InventoryItemDetail.class);  

Join<InventoryItemDetail, InventoryItem> joinItem = from.join(InventoryItemDetail_.inventoryItem); 

Predicate where = criteriaBuilder.lessThanOrEqualTo(from.get(InventoryItemDetail_.effectiveDate), date); 

Join<InventoryItem, Customer> joinCustomer = joinItem.join(InventoryItem_.customer, JoinType.LEFT); 
query.multiselect(joinItem.get(InventoryItem_.product),joinItem.get(InventoryItem_.facility),joinItem.get(InventoryItem_.customer)); 
query.groupBy(joinItem.get(InventoryItem_.product),joinItem.get(InventoryItem_.facility),joinCustomer); 
query.where(where); 

TypedQuery<InventoryItemSumReport> createQuery = getEm().createQuery(query);  
List<InventoryItemSumReport> resultList = createQuery.getResultList();