JPA Criteria query Path.get left join is it possible
criteria-api, java-ee-6, jpa-2.0
Solution
I found as follows it works:
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();
Problem
I have a question regarding JPA criteria. Here is my JPA criteria query: ``` 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(); ``` Here is the resulting query produced by the JPA provider: ``` 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 ``` But I would like the following query: ``` 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 ``` with a left join CUSTOMER to get also results where `Customers` are null. `Customer`, `Product`, `Facility` are all entites, while `InventoryItemSumReport` is a Value object or 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; } } ```