Wednesday, June 11, 2008

What I Like to See in JPA 2.0

What I like to see in JPA 2.0 final specification.

1. Support for setting collection parameters in JPQL: Collections<object> in a Query in places where a list of objects is acceptable. For example a very common issue is for 'IN' keyword in JPQL:

SELECT mo FROM MyObject mo WHERE mo.id IN (:idList)


Here users should be allowed to set a collection with underling elements of type MyObject.id.

2. Basic support for object comparison (equals) in JPQL:

manager.createQuery("SELECT b FROM Book b WHERE b.author = :p").setParameter("p", managedAuthorObject);

3. When writing an application-level generic search, it's almost impossible to use a NamedQuery. Many JPA 1.0 implementers (Hibernate and EclipseLink for example) support Query-by-example which makes life really much easier when writing search queries.

Since it's very likely that users (application-level) do not enter search criteria values (null values for criteria object), it's useful to let search work without setting some parameters (or setting them to a constant field meaning IGNORE). In this case a default action (which can be customized) can be taken. For example this case:

Query q = manager.createQuery("SELECT p FROM Person p WHERE p.name = :name AND p.age = :age");
if (name is available)
q.setParameter("name", name);
if (age is available)
q.setParameter("age", age);
q.findAll();


It would be really great if 2.0 spec force implementers to support a Query by example, something like this:

Person person = new Person("Bob", 28);
manager.findByExample(person);


A similar mechanism is currently supported by both Hibernate (Criteria query) and TopLink/EclipseLink.

4. LIKE operator for non-String fields. Some database engines support this, and it's good IMHO to recommend implementers to just ignore LIKE (in favor of == operation) if underlying DBMS doesn't support it.

5. Support for @GeneratedValue which is not also @Id. There are many cases that developers need to generate another unique value other that the original entity PK. Since now spec has SEQUENCE and IDENTITY, which are not portable to all DBMSes, @GeneratedValue may also be limited in some DBMSes.

6. Support for interceptors: events that are raised just before or after some special actions: @AfterCommit, @BeforeDelete, .... These annotations may be set globally on the BaseEntity class which is a @MappedSuperClass of other entities, in order to be applied on all entities. It's very useful for injecting different cross-cutting concerns.

7. More consistent persistence.xml schema among different implementations. Almost all configurations (from Database URL, to Logging level) are set as generic key-value pairs in persistence.xml. So in the simplest project you should have two different versions of persistence.xml, for instance one for EclipseLink and one for Hibernate. Many of these settings (specially database connection info) can be set through a general schema.

8. User may want to set another *.xml other than the one on META-INF/persistence.xml for configurations. It's very useful that PersistenceFactory allows a file name, URL, or InputStream to set as persistence.xml content.

A similar mechanism is currently supported by both Hibernate and TopLink.