Hi all,
I have taken a look at JPA 2.0 Criteria API, but I found it to be too cumbersome unlike Hibernate Criteria. Is there any good reason to use JPA 2.0 Criteria API rather than using JPA-QL? Thanks for your advise.
Hi all,
I have taken a look at JPA 2.0 Criteria API, but I found it to be too cumbersome unlike Hibernate Criteria. Is there any good reason to use JPA 2.0 Criteria API rather than using JPA-QL? Thanks for your advise.
JPA 2.0 Criteria API is The Object-based API for building queries. I think it can play a good job when you have a dynamic query which can become more readable as follows
cq.select(...)
.where(...)
.orderBy(...)
.groupBy(...);
But when using static query prefer To use an externalized, maintainable and readable file
<entity-mappings>
...
<named-query name="ORDER">
<query>
<![CDATA[
from
Order
]]>
</query>
</named-query>
<named-query name="ORDER_WITH_LINE_ITEM">
<query>
<![CDATA[
from
Order o
inner join fetch
o.lineItemList
]]>
</query>
</named-query>
...
</entity-mappings>
If you have a modularized application use one xml file for each module as follows
br
com
ar
moduleA
model
repository
moduleA.xml
moduleB
model
repository
moduleB.xml
moduleC
model
repository
moduleC.xml
Then you define your mappinf-file element
<mapping-file>br/com/ar/moduleA/model/repository/moduleA.xml</mapping-file>
<mapping-file>br/com/ar/moduleB/model/repository/moduleB.xml</mapping-file>
<mapping-file>br/com/ar/moduleC/model/repository/moduleC.xml</mapping-file>
Like the Hibernate Criteria API, the JPA 2.0 Criteria API is especially nice to build queries dynamically, to handle cases where the query structure varies depending upon runtime conditions.
But there is more. While being more verbose than Hibernate's Criteria API, the JPA Criteria API allows to build typesafe queries (if you use the Metamodel API). Below an example:
EntityManager em = ...
QueryBuilder qb = em.getQueryBuilder();
CriteriaQuery<Person> c = qb.createQuery(Person.class);
Root<Person> p = c.from(Person.class);
Predicate condition = qb.gt(p.get(Person_.age), 20);
c.where(condition);
TypedQuery<Person> q = em.createQuery(c);
List<Person> result = q.getResultList();
In the above snippet, the following would raise a compilation error for example:
Predicate condition = qb.gt(p.get(Person_.age, "xyz"));
In case you wonder, Person_
is the static, instantiated, canonical metamodel class corresponding to the original Person
entity class (generated by an annotation processor). It provides a strongly typed alternative to a runtime reflection based approach:
Field field = Person.class.getField("age");
Pros:
Cons:
I feel in general more comfortable with JPQL but the type safety of the Criteria API is a major difference with JPQL (and also the Hibernate Criteria API).
JPA 2 Criteria can be used in statically typed form if you generate the entity metamodel. It is more verbose then JPQL, but is statically typed and supports dynamic query construction directly.
The benefits of a statically typed query language is that you can catch more errors at compile time and IDE features like autocomplete can be used as well.