How to have order by on 2 fields (belonging to 2 separate entities) using criteria builder in java?

44 views Asked by At

I have a checklist instance object and inside one checklist instance there are multiple task objects (one-to-many relationship). I am using CriteriaBuilder to retrieve all checklist objects(which includes tasks as well). I want to fetch the checklists in a certain order (say on basis of it's created date, ascending order) and i want to fetch the tasks inside each checklist in another specific order (say on basis of it's due date, descending). I know how to fetch the the checklist object in that order using criteria order expressions as shown in the example below. But i want to know how to fetch the tasks for each checklist in the required fashion ?

 return jpaApi.withTransaction(em -> {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<ChecklistInstance> q = cb.createQuery(ChecklistInstance.class);
    Root<ChecklistInstance> instance = q.from(ChecklistInstance.class);
    List<Predicate> predicates = new ArrayList<>();
    predicates.add(cb.equal(instance.get(TaskConstants.CHECKLIST).get("id"), criteria.getChecklist()));
    q.orderBy(cb.asc(instance.get(TaskConstants.DUE_DATE)));
    q.select(instance).where(predicates.toArray(new Predicate[] {}));
    return em.createQuery(q).getResultList();
 });

 @Entity
 @Table(name = "tm_checklist_instance")
 public class ChecklistInstance implements Serializable {

     private static final long serialVersionUID = 1L;

     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private long id;

     private String guid;

     private String name;

     @OneToMany(targetEntity = Task.class, mappedBy = "checklistInstance", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
     private List<Task> tasks;
 }
1

There are 1 answers

3
Mohamed Bathaoui On

Add the @OrderBy annotation on the task list:

@OneToMany(targetEntity = Task.class, mappedBy = "checklistInstance", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
@OrderBy("due_date DESC")
 private List<Task> tasks;

Replace the "due_date" by your own field.

Hope this help ;)