Linda has written up the new typesafe query API. I previously blogged the reasoning behind this stuff here and here.

An open issue that Linda doesn't mention is query execution. I'm trying to convince the rest of the group that we should carry the typesafety all the way through to the query result set. Here's what I wrote to the group a few weeks ago:

Folks, I figured out a refactoring that gives us a way to do typesafe result sets, avoiding the use of Result. In this new approach, CriteriaQuery and Query would both have a type parameter. You could write code like this, if you have a single selection:
  CriteriaQuery<Order> q = qb.create(Order.class);
  Root<Order> order = q.from(Order.class);
  q.select(order);

  Query<Order> eq = em.createQuery(q);
  List<Order> res= eq.getTypedResultList();
like this, if you have multiple selections and an object to wrap them in:
  CriteriaQuery<OrderProduct> q = qb.create(OrderProduct.class);
  Root<Order> order = q.from(Order.class);
  Join<Item, Product> product = order.join(Order_.items)
                                     .join(Item_.product);
  q.select( qb.construct(OrderProduct.class, order, product) );

  Query<OrderProduct> eq = em.createQuery(q);
  List<OrderProduct> res= eq.getTypedResultList();
Or, if you don't have a nice wrapper class like OrderProduct, you can fall back to use Result:
  CriteriaQuery<Result> q = qb.create();
  Root<Order> order = q.from(Order.class);
  Join<Item, Product> product = order.join(Order_.items)
                                     .join(Item_.product);
  q.select( qb.result(order, product) );

  Query<Result> eq = em.createQuery(q);
  List<Result> res= eq.getTypedResultList();
This change let's people directly get typesafe lists of entities or wrappers, which is something that many people have asked for!

The big point about this API is that I can't write a query which selects Foo and then try to put it in a List<Bar>. It's truly typesafe, end-to-end.

The sticking point with this is that javax.persistence.Query does not currently have the needed type parameter, and there are millions of queries written to the JPA 1.0 APIs which would suddenly spit compiler warnings if we added a type parameter. So we might have to introduce a new interface like TypesafeQuery or something.


Back to top