Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice to generate a JPA dynamic, typed query?

i'm trying to convert a 'TableController'-Class we used (without ORM) to generate dynamic SQL (actually the order column and direction is appended to the SQL).

Think of this 'TableController' as a class that have a function to return a list of Entities of a given class (known at runtime), in a given order (String column/property name, boolean asc/desc, both at runtime).

The challenge is now, with JPA (Hibernate - but the customer requires to use JPA Interfaces only): How can i realize this without String concatenation, and in a type safe manner?

Thanks!

like image 975
Zeemee Avatar asked Oct 29 '10 08:10

Zeemee


1 Answers

The challenge is now, with JPA (Hibernate - but the customer requires to use JPA Interfaces only): how can I realize this without String concatenation, and in a type safe manner?

If you're using a JPA 2.0 implementation, I think you should look at the Criteria API to build dynamic queries.

If you're using JPA 1.0, there is no standard way apart from String concatenation (and my suggestion would be to use Hibernate's proprietary Criteria Queries).

The following article might also give you some (concrete) ideas: Hibernate Querying 102 : Criteria API.


Imagine a method that has three parameters: Class entityClass, String orderByColumn, boolean ascending. How would i create a query without string concatenation that gives me all objects of the given class in the correct order?

With the Criteria API from JPA 2.0, you could do something like this:

public <T> List<T> findAllEntitiesOrderedBy(Class<T> entityClass, String orderByColumn, boolean ascending) {
    CriteriaBuilder builder = em.getCriteriaBuilder();

    CriteriaQuery<T> criteria = builder.createQuery(entityClass);
    Root<T> entityRoot = criteria.from(entityClass);
    criteria.select(entityRoot);
    javax.persistence.criteria.Order order = ascending ? builder.asc(entityRoot.get(orderByColumn))
        : builder.desc(entityRoot.get(orderByColumn));
    criteria.orderBy(order);
    return em.createQuery(criteria).getResultList();
}
like image 81
Pascal Thivent Avatar answered Oct 10 '22 04:10

Pascal Thivent