JPA 2.0 to better support Java Generics with Typesafe Support and Criteria Selection

With JPA 1.0 the @SuppressWarnings annotation seemed common whenever using a Query object to return collections using generics.

	public List<Brand> getBrands() {
    		Query query = entityManager.createQuery("select b from Brand b");
    		List<Brand> s = (List<Brand>)query.getResultList();
    		return s; 

Unfortunatly JPA 1.0 does not have typesafe support available. With the release of JPA 2.0, classes such as TypedQuery and CriteriaQuery were introduced to account for this shortcoming. These classes can be used to pass

Below shows an example of using JPQL with a TypedQuery

	public List<Brand> getBrands() {
    		TypedQuery<Brand> q = entityManager.createQuery("select b from Brand b", Brand.class);
    		List<Brand> s = query.getResultList();
    		return s; 

JPA 2.0 has also introduced the javax.persistence.criteria package to better perform criteria searches. This can be used instead of JPQL to better typesafe parameters.

	public List<Item> getItemsForCostLessThan(Double cost) {
    		Query query = entityManager.createQuery("select i from Item i where i.cost < ?1");
    		query.setParameter(1, cost);
    		List<Item> s = (List<Item>)query.getResultList();
    		return s; 

This entire JPQL can be above can be rewritten to become typesafe using JPA generics as shown below.

	public List<Item> getItemsForCostLessThan(Double cost) {
    		QueryBuilder qb = entityManager.getQueryBuilder();
    		CriteriaQuery<Item> c = qb.createQuery(Item.class);
    		Root<Item> p = c.from(Item.class);
    		Predicate condition = qb.lt(p.get(Item_.cost), 19.99);
    		TypedQuery<Item> q = em.createQuery(c); 
    		List<Item> result = q.getResultList();
    		return result; 

It is pretty straight forward that uses typesafe design with JPA classes doing all the work. This solution has more code, but is much less error prone due to type checking that occurs. Just like the JPQL was designed from hibernate's HSQL, it looks like JPA's criteria package was mirrored after hibernate's existing criteria package.

The only question that a new pair of eyes may have is the Item_.cost reference. This class is generated from JPA's 2.0 Metamodel of the Item class. The cost field from the Item_ class is static and references to the cost field from the Item class.


Anonymous, Tue, 12/14/2010 - 13:31

In which jar did you find the EntityManager.getQueryBuilder() method?

Thanks very much!

David, Mon, 08/22/2011 - 19:38

It was in the JSR 317 spec originally for JPA 2.0. I believe it has changed a bit. This can easily be changed to use the final spec. I will change the example if I ever find time :)


Post new comment

Subscribe to Syndicate