JOIN using the ON condition

The ON clause in SQL is used to specify the relationship between the tables. It is different from the WHERE clause which specifies the criteria for the rows to be picked.

The join condition used for a join comes from the mapping's join columns. This means that the JPQL user is normally free from having to know how every relationship is joined. In some cases it is desirable to append additional conditions to the join condition, normally in the case of outer joins. This can be done through the ON clause. Here's an example of a JOIN using the ON clause:


SELECT e FROM Employee e LEFT JOIN e.address ON a.city = :city

Support for downcast in JPQL

JPQL will be extended to cast in the FROM clause. The format of this will use the keyword "TREAT" and be part of the join clause. The following is an example:


SELECT b.name 
FROM User e JOIN TREAT(e.projects AS LargeProject) b

In this example, the join is performed between User and Project but name is an attribute of the Project class which is a subclass of the LargeProject class. 

Support for Functions in JPQL

SQL supports a lot more database functions than JPQL. Specific database vendors also provide their own set of functions. Users and libraries can also define their own database functions. JPA 2.0 JPQL provided no mechanism to call database specific functions. The JPA 2.1 spec defines a special FUNCTION operator in JPQL to allow calling a specific database function:


SELECT FUNCTION('YEAR', e.startDate) AS year, COUNT(e) FROM Employee e GROUP BY year

Criteria Bulk updates and deletes:

The Criteria framework is an API for creating typesafe and/or dynamic Java Persistence queries.  In previous version of the specification support for "UPDATE Employee e SET e.salary = :salary" and similar delete JPQL was not available using the Criteria API. Through the addition of CriteriaUpdate/CriteriaDelete classes support for bulk update/delete queries has now been added.

Here's an example of Criteria Updates which allows a minimal wage of 2000 to every Employee:

CriteriaUpdate<Employee> q = cb.createCriteriaUpdate(Employee.class);
Root<Employee> c = q.from(Employee.class);
q.set(c.get(Employee.wage), 2000)
 .where(c.lt(c.get(Employee.wage), 2000));

with the equivalent JPQL of:
UPDATE Employee e
SET e.wage = 2000
WHERE e.wage < 2000

This query can then be executed as:
@PersistenceContext EntityManager em;
Query query = em.createQuery(q);
query.executeUpdate();

CDI listeners in Entity classes

Entity listeners using CDI: Entity Listeners allow to handle cross-cutting lifecycle events in a non-persistent listener class. In JPA 2.1, entity listeners will support dependency injection through CDI. The usual lifecycle callback methods of @PrePersist, @PostPersist, @PreUpdate, and @PreRemove can be used for entities. The entity listeners can also be annotated with @PostConstruct and @PreDestroy for their own lifecycle.

Example:

@Entity 
@EntityListeners(Alarm.class)
public class Customer {
@Id private Integer id;
private String name;
...
 
}

public class Alarm {
  @PostPersist 
  public void alert(Customer c) {
    
    ...
  }
}

Dynamically defined named queries

With JPA 2.1 it is now possible to define at runtime named queries: this can be useful for queries which are frequentely used but need to be parametrized:

@PersistenceContext EntityManager em;

EntityManagerFactory emf = em.getEntityManagerFactory();
emf.addNamedQuery("supplierStatus",
      em.createQuery("SELECT e.name FROM Employee e WHERE e.status = :status")
);

Eager to test JPA 2.1 ? At the time of writing there is no container support for JPA 2.1, however you could give a try to hibernate-JPA 2.1 draft library which is available through the following dependency:


<dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.1-api</artifactId>
    <version>1.0.0.Draft-6</version>
</dependency>

References: https://blogs.oracle.com/arungupta/entry/jpa_2_1_early_draft

0
0
0
s2smodern