Path navigation is nothing but accessing entity properties by using dot (.) operator (for example in JPQL: employee.name, employee.address.city).
In JPA Criteria API, path navigation is performed by the use of Path interface (a subinterface of Expression ). The interfaces Root , From and Join are the subinterfaces of Path .
A Path instance can be further navigated via Path#get() method.
Quick example:
CriteriaQuery<Item> query = criteriaBuilder.createQuery(Item.class);
Root<Customer> customer = query.from(Customer.class);
ListJoin<Order, Item> items = customer.join(Customer_.orders)
.join(Order_.items);
query.select(items)
.where(criteriaBuilder.equal(customer.get(Customer_.shipmentInfo)
.get(ShipmentInfo_.address)
.get(Address_.state), "NJ"));
Example
Entities
@Entity
public class Customer {
@Id
@GeneratedValue
private long id;
private String name;
@OneToMany(cascade = CascadeType.ALL)
private List<Order> orders;
@OneToOne(cascade = CascadeType.ALL)
private ShipmentInfo shipmentInfo;
.............
}
@Entity
@Table(name = "CustomerOrder")
public class Order {
@Id
@GeneratedValue
private long id;
private LocalDate date;
@OneToMany(cascade = CascadeType.ALL)
private List<Item> items;
.............
}
@Entity
public class Item {
@Id
@GeneratedValue
private long id;
private String name;
BigDecimal price;
.............
}
@Entity
public class ShipmentInfo {
@Id
@GeneratedValue
private long id;
private String phone;
@OneToOne(cascade = CascadeType.ALL)
private Address address;
.............
}
@Entity
public class Address {
@Id
@GeneratedValue
private long id;
private String street;
private String city;
private String state;
private String zipCode;
.............
}
Performing path navigation
public class ExampleMain {
private static EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("example-unit");
public static void main(String[] args) {
try {
persistCustomers();
findOrderItems();
} finally {
entityManagerFactory.close();
}
}
public static void persistCustomers() {
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
Customers.getCustomers().forEach(em::persist);
em.getTransaction().commit();
System.out.println("-- Customers persisted --");
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> query = cb.createQuery(Customer.class);
query.select(query.from(Customer.class));
em.createQuery(query).getResultList().forEach(System.out::println);
em.close();
}
private static void findOrderItems() {
System.out.println("-- find order items placed from state NJ --");
EntityManager em = entityManagerFactory.createEntityManager();
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Item> query = criteriaBuilder.createQuery(Item.class);
Root<Customer> customer = query.from(Customer.class);
ListJoin<Order, Item> items = customer.join(Customer_.orders)
.join(Order_.items);
query.select(items)
.where(criteriaBuilder.equal(customer.get(Customer_.shipmentInfo)
.get(ShipmentInfo_.address)
.get(Address_.state), "NJ"));
em.createQuery(query).getResultList().forEach(System.out::println);
}
} -- Customers persisted -- Hibernate: select customer0_.id as id1_1_, customer0_.name as name2_1_, customer0_.shipmentInfo_id as shipment3_1_ from Customer customer0_ Customer{id=1, name='Mike', orders=[Order{id=4, date=2018-07-05, items=[Item{id=5, name='Desktop', price=621}, Item{id=6, name='Monitor', price=530}, Item{id=7, name='SSD', price=733}, Item{id=8, name='Keyboard', price=464}]}], shipmentInfo=ShipmentInfo{id=2, phone='387121', address=com.logicbig.example.Address@2b87581}} Customer{id=9, name='Sara', orders=[Order{id=12, date=2017-04-07, items=[Item{id=13, name='Backpack', price=406}, Item{id=14, name='Lamp', price=381}, Item{id=15, name='Saucepan', price=695}, Item{id=16, name='Food Processor', price=253}]}], shipmentInfo=ShipmentInfo{id=10, phone='941117', address=com.logicbig.example.Address@61d01788}} Customer{id=17, name='Charlie', orders=[Order{id=20, date=2017-01-22, items=[Item{id=21, name='Chivas', price=366}, Item{id=22, name='Merlot', price=262}, Item{id=23, name='Sapphire', price=245}, Item{id=24, name='Johnnie', price=707}]}], shipmentInfo=ShipmentInfo{id=18, phone='654184', address=com.logicbig.example.Address@56ccd751}} -- find order items placed from state NJ -- Hibernate: select item4_.id as id1_5_, item4_.name as name2_5_, item4_.price as price3_5_ from Customer customer0_ inner join Customer_CustomerOrder orders1_ on customer0_.id=orders1_.Customer_id inner join CustomerOrder order2_ on orders1_.orders_id=order2_.id inner join CustomerOrder_Item items3_ on order2_.id=items3_.Order_id inner join Item item4_ on items3_.items_id=item4_.id cross join ShipmentInfo shipmentin5_ cross join Address address6_ where customer0_.shipmentInfo_id=shipmentin5_.id and shipmentin5_.address_id=address6_.id and address6_.state=? Item{id=5, name='Desktop', price=621.00} Item{id=6, name='Monitor', price=530.00} Item{id=7, name='SSD', price=733.00} Item{id=8, name='Keyboard', price=464.00}
The equivalent JPQL of above example will be:
public class ExampleMain2 {
private static EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("example-unit");
public static void main(String[] args) {
try {
persistCustomers();
findOrderItems();
} finally {
entityManagerFactory.close();
}
}
public static void persistCustomers() {
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
Customers.getCustomers().forEach(em::persist);
em.getTransaction().commit();
System.out.println("-- Customers persisted --");
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> query = cb.createQuery(Customer.class);
query.select(query.from(Customer.class));
em.createQuery(query).getResultList().forEach(System.out::println);
em.close();
}
private static void findOrderItems() {
System.out.println("-- find order items placed from state NJ using JPQL --");
EntityManager em = entityManagerFactory.createEntityManager();
TypedQuery<Item> query = em.createQuery("Select itm from Customer c"
+ " JOIN c.orders o JOIN o.items itm where"
+ " c.shipmentInfo.address.state = 'NJ'", Item.class);
query.getResultList()
.forEach(System.out::println);
}
} -- Customers persisted -- Hibernate: select customer0_.id as id1_1_, customer0_.name as name2_1_, customer0_.shipmentInfo_id as shipment3_1_ from Customer customer0_ Customer{id=1, name='Mike', orders=[Order{id=4, date=2017-03-14, items=[Item{id=5, name='Desktop', price=689}, Item{id=6, name='Monitor', price=541}, Item{id=7, name='SSD', price=787}, Item{id=8, name='Keyboard', price=749}]}], shipmentInfo=ShipmentInfo{id=2, phone='908399', address=com.logicbig.example.Address@2b87581}} Customer{id=9, name='Sara', orders=[Order{id=12, date=2017-04-15, items=[Item{id=13, name='Backpack', price=472}, Item{id=14, name='Lamp', price=241}, Item{id=15, name='Saucepan', price=284}, Item{id=16, name='Food Processor', price=255}]}], shipmentInfo=ShipmentInfo{id=10, phone='735346', address=com.logicbig.example.Address@61d01788}} Customer{id=17, name='Charlie', orders=[Order{id=20, date=2017-10-05, items=[Item{id=21, name='Chivas', price=500}, Item{id=22, name='Merlot', price=315}, Item{id=23, name='Sapphire', price=696}, Item{id=24, name='Johnnie', price=437}]}], shipmentInfo=ShipmentInfo{id=18, phone='692075', address=com.logicbig.example.Address@56ccd751}} -- find order items placed from state NJ using JPQL -- Hibernate: select item4_.id as id1_5_, item4_.name as name2_5_, item4_.price as price3_5_ from Customer customer0_ inner join Customer_CustomerOrder orders1_ on customer0_.id=orders1_.Customer_id inner join CustomerOrder order2_ on orders1_.orders_id=order2_.id inner join CustomerOrder_Item items3_ on order2_.id=items3_.Order_id inner join Item item4_ on items3_.items_id=item4_.id cross join ShipmentInfo shipmentin5_ cross join Address address6_ where customer0_.shipmentInfo_id=shipmentin5_.id and shipmentin5_.address_id=address6_.id and address6_.state='NJ' Item{id=5, name='Desktop', price=689.00} Item{id=6, name='Monitor', price=541.00} Item{id=7, name='SSD', price=787.00} Item{id=8, name='Keyboard', price=749.00}
As seen in outputs, in both of above cases the same select statement was executed by Hibernate to find 'items'.
Example ProjectDependencies and Technologies Used: - h2 1.4.197: H2 Database Engine.
- hibernate-core 5.3.5.Final: Hibernate's core ORM functionality.
Implements javax.persistence:javax.persistence-api version 2.2 - hibernate-jpamodelgen 5.3.5.Final: Annotation Processor to generate JPA 2 static metamodel classes.
- JDK 1.8
- Maven 3.5.4
|
|