2017-10-04 1 views
0

Je cherche à faire un contrôleur REST qui retournera une liste triée de divers objets.Grouper et trier une collection de collections en utilisant JPA

J'ai créé un DTO pour tenir ces collections comme les suivantes, mais cela ne fonctionnera pas comme groupera par entité:

public class AllReportsDTO { 

private List<AReport> aReports; 
private List<BReport> bReports; 
private List<CReport> cReports; 
... 
} 

J'ai alors les objets de domaine suivant

@Entity 
@Table(name = "a_report") 
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
public class AReport implements Serializable { 

private static final long serialVersionUID = 1L; 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

@Column(name = "title") 
private String title; 

@Column(name = "description") 
private String description; 

@Column(name = "time_of_report") 
private ZonedDateTime timeOfReport; 

Et un pour chaque rapport. Ce que je veux faire est de créer un point de terminaison qui retournera une liste de tous ces rapports, mais dans l'ordre de temps du rapport et non groupés par rapport. Comment puis-je atteindre cet objectif? J'ai essayé de l'écrire dans le référentiel avec une requête HQL et de le grouper par le temps, mais le problème est que chaque champ a un nom différent dans chaque rapport que je ne peux pas modifier car ce système est utilisé dans d'autres endroits .

+1

Faire classe séparée pour la représentation JSON de votre entité « rapport » et utilisez @JsonPropertyOrder –

+0

Salut Sujal , Merci beaucoup pour votre réponse. Le problème est que chaque rapport a très peu de variables en commun, il serait donc difficile de créer la représentation JSON comme une vue commune. Le plus gros problème est également que les noms des variables pour l'heure sont nommés différemment, ce que je ne peux pas changer, donc ce serait difficile à commander. – Megadec

+1

Je ne comprends pas. Premièrement: un 'Set' rendra votre commande par le temps obsolète car elle ne garantit aucun ordre. Vous devez passer à 'List'. Deuxièmement: s'il y a différentes entités, sélectionnez-les séparément et dans chaque requête, vous pouvez les trier par le champ de l'heure actuelle. –

Répondre

1

Je ne voudrais pas essayer une solution HQL pure, ou une solution de votre ORM. J'irais à la manière de Java.

  1. Ajouter une interface

    public interface ITimedReport { 
        ZonedDateTime getTime(); 
    } 
    
  2. Faites toute votre classe rapport implémente cette interface en retournant leur propre timestamp
  3. Ajouter une méthode getAllReports sur AllReportsDTO. Cette méthode doit remplir un List<ITimedReport> avec tous les rapports, puis trier la liste avec un Comparator<ITimedReport>. Ce comparateur s'appuierait sur le getTime() pour comparer.

Vous pouvez ajouter quoi que ce soit meaningfull un rapport dans l'interface, comme un getTitle, getDescription, ...

+0

Merci Genu! C'est une solution très élégante. – Megadec

2

Vous pouvez créer une méthode qui trie vos ensembles. Essayez d'adepte celui-ci

Collections.sort(aReports, new Comparator<Object>() { 
    public int compare(MyObject o1, Object o2) { 
     return o1.getTimeOfReport().compareTo(o2.getTimeOfReport()); 
    } 
});