The Java Specification Request 317 (JSR-317) aka JavaTM Persistence 2.0, (JPA 2.0) has finally reached the last stage, “Completion of Reference Implementation (RI) and Technology Compatibility Kit (TCK)”, before it’s officially released. Therefore last week a Knowledge Class was given at Amis with a presentation of the new functionality and differences compared to JPA 1.0 and some hands-on exercises.
The presentation covered the following topics:
- Standard properties in persistence.xml
- Mixed @AccessType
- Derived Identifiers
- Undirectional @OneToMany / @OneToOne
- Shared Cache API
- JP QL
- Expression and criteria API
The main new hot topic of JPA 2.0, the new criteria API, has been changed dramatically in the past year and a complete new object model has been chosen, so no DomainObject and QueryDefiniton objects any more! Unfortunately the RI of EclipseLink has not been finished for the new criteria API, thus the hands-on only had exercises about less exciting differences.
At the end of the presentation a little discussion started about the pro and cons of the new criteria API. The presentation contains some code examples and the consensus was that the code was quite hard to read and understand comparing with the JP QL variant. Especially from a maintenance perspective this is a disadvantage. On the other hand, the new criteria API is type safe, so that will be an advantage. But that can also be a risk! Because of type safety, programmers might tend to skip writing good unit tests that covers all the query condition branches. Experienced programmers know this really is needed in order to test if the tested query does return the correct data in all the specified conditions. But when a unit test covering all condition branches is still needed, you can as well use JP QL, which is far more readable and easier to understand.
However there is one more advantage of the criteria API above JP QL and that is in the situation of creating a query dynamically, depending on the combination of available (user entered) search params. This is a quite common situation every developer will recognize, for example at search forms in web applications.
With JP QL you have to execute the logic code twice! One time to create the JP QL query and one time more to assign the values to the bind params. This often leads to redundant and error prone code. With the criteria API you can create the query in one ‘round trip’.
From the audience the suggestion came up of defining/creating the complete query once, so without logic code and with boolean arguments enable and disable the ‘AND’ and ‘OR’ expression of the query. That would indeed be quite nice! This implies that the ‘and()’ and the ‘or()’ method of the QueryBuilder object have a boolean argument to enable/disable the condition, which is not the case of the current JPA 2.0 specs.
Also the suggestion came up that for logging and debugging purposes it would be quite nice if the CriteriaQuery object (or the finally created Query object) is able to parse itself to a SQL or JP QL string. This means a method like
String toSQL() or
String toJPQL() will be needed on the CriteriaQuery and/or Query object.
I’ve discussed these last two suggestions with my colleague Wouter van Reeven and we decided to submit them as change requests to the JSR317 team. Obvious these requests are too late for the JPA 2.0 specs, but hopefully they will taken into account for a future JPA spec. We’re already curious about the JPA 2.1 specs!