A blog mainly about Java

JPA 2.0 Criteria API with Maven and EclipseLink

For those of you who have followed the JPA 2.0 specification, you might have come across the new Criteria API. The main idea of this new API is to be able to write a JPQL query using an object-oriented way (through a rich API) instead of a String. For example, if you want to return the list of all customers who are called John, you will write the following JQPL query :

SELECT c FROM Customer c WHERE c.firstName = 'John'

This is a String and many typos can be made. For example you could have typos on JPQL keywords (SLECT instead of SELECT), class names or attributes. You can also write a syntactically incorrect statement (SELECT c WHERE c.firstName = 'John' FROM Customer). And when do you discover that your statement is incorrect ? At runtime ! JPA 2.0 comes with a rich criteria API (in the package javax.persistence.criteria) allowing you to write any JQPL query in an object and syntactically correct way (at compile time). All JPQL keywords (SELECT, FROM, WHERE, LIKE, GROUP BY…) are defined in this API. So the previous JPQL statement can be written as follow (em being the Entity Manager) :

As you can see, this statement is not completely type safe : the attribute firstName is a String. JPA 2.0 comes with this idea of meta-model. Each entity has a static meta-model class generated by JPA describing its meta-data. The convention is that each entity X will have a meta-data class called X_ (with an underscore). So, the Customer entity will have its representation described in Customer_. You can then write the previous query in a type safe (Customer_.firstName) way as follow :

How do you get these meta data ? With annotation processor. Here is how you can configure with Intellij IDEA and Maven.

Intellij IDEA

Intellij Idea can help you to generate the meta-model classes on the fly. You need to configure the EclipseLink annotation processor (org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor) as shown on the image below, and make sure that your Intellij IDEA project is setup with Java 1.6 (the CanonicalModelProcessor only works with 1.6). Then, you can run the process annotation (Ctrl+Alt+Maj+F9) and get the meta-classes generated.

Maven

But when it comes to continues integration, your IDE is not enough, you need you favourite building tool to do the job. And my favourite building tool is Maven (I would never have though to write favourite and Maven in the same sentence). Maven needs to invoke the annotation processor of EclipseLink to generate the meta-classes during the generate-sources goal phase with the maven-processor-plugin. So here is the pom.xml to make this work (JPA and EclipseLink dependencies + the plugin configuration) :

As you can see, each attribute is of type SingularAttribute (but it could have been a CollectionAttribute for attributes of type Collection). You can check all the available meta-model types in the javax.persistence.metamodel package.

Other queries

The Criteria API has all the needed methods to write complex queries. Here is a glimpse of what you can write with this new API (with or without meta-model classes) :