Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Complex queries with JPA Criteria builder

Can someone suggest me how to build up the following query using JPA Criteria builder API?

SELECT id,status,created_at from transactions where status='1' 
   and currency='USD' and appId='123' order by id

It's better if I can find a solution which creates dynamically based on the parameters given as a Map<String,String> using metamodel classes or any other way.

like image 800
Aina Ari Avatar asked Oct 01 '10 18:10

Aina Ari


1 Answers

It's like this (without metamodel):

Map<String, Object> params = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();           
CriteriaQuery<Tuple> cq = cb.createTupleQuery();     
Root<Transaction> r = cq.from(Transaction.class);

Predicate p= cb.conjunction();
for (Map.Entry<String, Object> param: params.entrySet())
    p = cb.and(p, cb.equal(r.get(param.getKey()), param.getValue()));

cq.multiselect(r.get("id"), r.get("status"), r.get("created_at"))
    .where(p)
    .orderBy(cb.asc(r.get("id")));

List<Tuple> result = em.createQuery(cq).getResultList();

Or with metamodel (typesafe, but a bit wordy):

Map<SingularAttribute<Transaction, ?>, Object> params = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();           
CriteriaQuery<Tuple> cq = cb.createTupleQuery();     
Root<Transaction> r = cq.from(Transaction.class);

Predicate p= cb.conjunction();
for (Map.Entry<SingularAttribute<Transaction, ?>, Object> param: params.entrySet())
    p = cb.and(p, cb.equal(r.get(param.getKey()), param.getValue()));

cq.multiselect(r.get(Transaction_.id), r.get(Transaction_.status), 
          r.get(Transaction_.created_at))
    .where(p)
    .orderBy(cb.asc(r.get(Transaction_.id)));

List<Tuple> result = em.createQuery(cq).getResultList();
like image 193
axtavt Avatar answered Sep 28 '22 05:09

axtavt