1. JPA 2.0 Whatâs new? Emiel Paasschens Ref. implemenatie van EclipseLink is bijlange (met name Criteria API) nanognietaf, dus⌠GEEN Hands-Onď of tochwelâŚ
21. Can be mixed now! (instead of one or the other)At Entity/Class level the default Access type is defined
22. Can be set per attribute to differ from default: - on field (declaration) @Access(FIELD) ď access directly on instance variable by pers.prov.- on property (getter accessor) @Access(PROPERTY) ď access via accessor methods by pers. prov.
23. Be aware: @Access(PROPERTY):- validation/conversion logic in accessor methods is executed!- exceptions are catched and wrapped in PersistenceException, which is thrown. Transactions are marked for rollback.
28. Duplicate mapping info@Entity public class Part { @Id Integer partNo; @Column(name=âSUPP_IDâ) @Id Integer suppId; ... @ManyToOne(insertable=false, updatable=false) @JoinColumn(name=âSUPP_IDâ) Supplier supplier; ... }
29.
30.
31.
32. Can be combined with existing @Column (only with basic type) and @OrderBy annotations
33.
34. Undirectional @OneToMany / @OneToOne @OneToMany Mapping with @JoinColumn on parent side: Â @Entity public class Vehicle { ... @OneToMany @JoinColumn(name=âVEHICâ) List<Parts> parts; ... } Â Also applies to @OneToOne With JPA 1.0 you had to define relation on both sides (necessary to specify columnname)
35.
36. Stores the order in separate DB column, so preferable do not use! ď insert object at begin of list causes lots of updates!
37.
38.
39. evict? ď how about objects pointing to these evicting instancesâŚ
50. The query Root object defined by the from method and is analog to the âEmployee eâ in JP QL: SELECT e FROM Employee e
51. new Query object is created by passing CriteriaQuery to em.createQuery.
52.
53. Also applies for and(), or() and not(), methods of the QueryBuilder API
54. The same accounts for methods in the select: max(), min(), sum(), prod(), etc
55. But the orderBy(), groupBy() and having() are methods of the CriteriaQueryobject!
56. And function desc() and asc() are methods of the QueryBuilderobject !!Pro is type safe and no need any more to execute logic code twice when dynamically constructing a query comparing with JP QL (where one time parse is needed to construct the query query and one more to bind the bind params). Con : quite complex and hard to read, so from maintenance perspectiveâŚ
57. Expression & criteria API (code) Query q = em.createQuery(âSELECT a FROM Account aâ); QueryBuilderqb = em.getQueryBuilder();CriteriaQuerycq = qb.create(); Root<Account> account = cq.from(Account.class); cq.select(account); Query q = em.createQuery(cq); List<Account> list = q. getResultList(); Â
58. Expression & criteria API (code) SELECT c.name FROM Customer c JOIN c.orders o JOIN o.lineitemsi WHERE i.product.productType = âprinterâ CriteriaQuery q = qb.create(); Root<Customer> cust = q.from(Customer.class); Join<Customer, Order> order = cust.join(Customer_.orders); Join<Order, Item> item = order.join(Order_.lineitems); q.select(cust.get(Customer_.name)) .where(qb.equal(item.get(Item_.product).get(Product_.productType), "printer"));
59. Expression & criteria API (code) Joins can be chained, resulting into: Â CriteriaQueryq = qb.create(); Root<Customer> cust = q.from(Customer.class); Join<Order,Item> item = cust.join(Customer_.orders).join(Order_.lineitems); q.select(cust.get(Customer_.name)) .where(qb.equal(item.get(Item_.product).get(Product_.productType), "printer")); Â Â Outer join with param on the join: SELECT c FROM Customer c LEFT JOIN c.orders o WHERE c.status = 1 Â CriteriaQuery q = qb.create(); Root<Customer> cust = q.from(Customer.class); Join<Customer, Order> order = cust.join(Customer_.orders, JoinType.LEFT); q.where(qb.equal(cust.get(Customer_.status), 1)).select(cust);
60. Expression & criteria API (code) Example with ContactInfo as Embeddable class containing address and set of Phones. Â SELECT p.vendor FROM Employee e JOIN e.contactInfo.phones p WHERE e.contactInfo.address.zipcode = '95054' Â CriteriaQuery q = qb.create(); Root<Employee> emp = q.from(Employee.class); Join<ContactInfo, Phone> phone = emp.join(Employee_.contactInfo).join(ContactInfo_.phones); q.where(qb.equal(emp.get(Employee_.contactInfo).get( ContactInfo_.address).get(Address_.zipcode), "95054")).select(phone.get(Phone_.vendor));
61. Expression & criteria API (code) Example with subquery using all:SELECT emp FROM Employee emp WHERE emp.salary > ALL (SELECT m.salary FROM Manager m WHERE m.department = emp.department) Â Â // create CriteriaQuery instance, with root Employee CriteriaQuery q = qb.create(); Root<Employee> emp = q.from(Employee.class); Â // create Subquery instance, with root Manager Subquery<BigDecimal> sq = q.subquery(BigDecimal.class); Root<Manager> manager = sq.from(Manager.class); sq.select(manager.get(Manager_.salary)); sq.where(qb.equal(manager.get(Manager_.dept), emp.get(Employee_.dept))); Â // an all expression is applied to the subquery result q.select(emp).where(qb.gt(emp.get(Employee_.salary), qb.all(sq)));
62. Expression & criteria API (code) Example with order by: SELECT o.quantity, a.zipcode FROM Customer c JOIN c.orders o JOIN c.address a WHERE a.state = 'CAâ ORDER BY o.quantity, a.zipcode CriteriaQuery q = qb.create(); Root<Customer> c = q.from(Customer.class); Join<Customer, Order> o = c.join(Customer_.orders); Join<Customer, Address> a = c.join(Customer_.address); q.where(qb.equal(a.get(Address_.state), "CA")); q.orderBy(qb.asc(o.get(Order_.quantity)), qb.asc(a.get(Address_.zipcode))); q.select(o.get(Order_.quantity), a.get(Address_.zipcode));
63. Expression & criteria API (code) Example with group by and having: SELECT c.status, AVG(c.filledOrderCount), COUNT(c) FROM Customer c GROUP BY c.status HAVING c.status IN (1, 2) CriteriaQuery q = qb.create(); Root<Customer> cust = q.from(Customer.class); q.groupBy(cust.get(Customer_.status)); q.having(qb.in(cust.get(Customer_.status)).value(1).value(2)); q.select(cust.get(Customer_.status), qb.avg(cust.get(Customer_.filledOrderCount)), qb.count(cust));