2017-09-12 5 views
0

J'ai un objet d'instance de liste de contrôle et, à l'intérieur d'une instance de liste de contrôle, il y a plusieurs objets de tâche (relation un-à-plusieurs). J'utilise CriteriaBuilder pour récupérer tous les objets de la liste de contrôle (y compris les tâches). Je veux aller chercher les listes de contrôle dans un certain ordre (disons en fonction de leur date de création, ordre croissant) et je veux aller chercher les tâches dans chaque liste de contrôle dans un autre ordre spécifique (par exemple date d'échéance, descendant). Je sais comment récupérer l'objet de la liste de contrôle dans cet ordre en utilisant des expressions d'ordre de critères comme indiqué dans l'exemple ci-dessous. Mais je veux savoir comment récupérer les tâches pour chaque liste de contrôle de la manière requise?Comment passer commande sur 2 champs (appartenant à 2 entités distinctes) en utilisant le constructeur de critères en java?

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; 
} 
+0

Quelqu'un peut-il aider? –

+0

Tout d'abord, je préfère utiliser Set intead de List. C'est plus pratique. Pour votre question, je suggère d'utiliser un TreeSet pour définir la liste des tâches, et implémenter l'interface Comparable sur l'entité Task. Vous pouvez ensuite implémenter votre propre commande comme vous le souhaitez;) –

+0

@MohamedBathaoui Non mais je veux utiliser le générateur de requête de critères uniquement pour implémenter la commande. Comment faire ? –

Répondre

0

Ajouter l'annotation @OrderBy sur la liste des tâches:

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

Remplacer la "due_date" par votre propre domaine.

Espérons que cette aide;)

+0

En fait, l'ordre par champ n'est pas un champ fixe. Cela varie selon certaines conditions. par exemple. Si je veux récupérer toutes les instances de la checklist OPEN alors je veux que les tâches (associées aux instances) soient triées par ordre de dates, alors que si je veux récupérer toutes les instances de checklist terminées je veux que les tâches soient triées par ordre de dates complétées Comment pouvons-nous placer un ordre conditionnel soit dans la classe d'entité comme vous le suggérez, soit en construisant les critères demandés par moi dans la question? –

+0

Une idée les gars? –

+0

Une bonne solution consiste à utiliser TreeSet et à utiliser l'interface Comparator (au lieu de l'interface Comparable) pour répondre au tri conditionnel des tâches. Personnellement, je n'ai pas la solution avec CriteriaBuilder. –