Résultat de type pivot avec JPA / QueryDSL

Nous utilisons JPA2, Spring Data et QueryDSL dans notre projet. J’ai les tables suivantes et les entités JPA associées:

table Person (id, ...) table Activity (id, type, ...) @Entity @Configurable public class Activity { @ElementCollection @CollectionTable(joinColumns = @JoinColumn(name = "ACTIVITY_ID")) @NotEmpty @Valid private Set names = new HashSet(); table ActivityName(activity_id, name, ...) @Embeddable @Immutable @Table(uniqueConstraints = @UniqueConstraint(columnNames = "NAME")) public static class ActivityName { ... } table ActivityLevel(person_id, activity_id, level) @Entity @Immutable @Validated public final class ActivityLevel{...} 

1..n pour Actitivy to ActivityName – une activité peut avoir des noms différents (par exemple, courir, faire du jogging)

Une personne peut avoir un certain niveau pour une activité donnée et peut effectuer plusieurs activités (chacune avec un niveau défini).

  • Il doit exister une recherche avec des noms d’activités (par exemple, en cours d’exécution, etc.) en tant que parameters (une liste de noms d’activités).
  • En conséquence, il convient de rechercher toutes les personnes effectuant l’activité connexe.
  • Le résultat doit contenir toutes les activités recherchées avec leur niveau correspondant, le nom de la personne et la sum globale de ses activités.

Exemple les données suivantes:

  • Personne = (id = 1, nom = Bob)
  • Personne = (id = 2, nom = Marie)
  • Activité = (1, …)
  • Activité = (2, …)
  • NomActivité = (id_activité = 1, nom = “jogging”)
  • NomActivité = (id_activité = 1, nom = “en cours d’exécution”)
  • NomActivité = (id_activité = 2, nom = “dansant”)
  • ActivityLevel = (person_id = 1, activity_id = 1, level = 0.7f)
  • ActivityLevel = (person_id = 1, activity_id = 2, level = 0.1f)
  • ActivityLevel = (person_id = 2, activity_id = 1, level = 0.5f)

La recherche de personnes qui “courent” ou “dansent” devrait donner un résultat comme celui-ci:

 Person[Name] ActitiyName ActivityLevel ActitiyName ActivityLevel Sum Bob running 0.7 dancing 0.1 0.8 Mary running 0.5 0.5 

Ma question: Existe t-il un moyen JPA QL / QueryDSL d’obtenir un tel résultat avec une seule expression / projection? Ce que je possède déjà, c’est une solution en plusieurs étapes: sélection des noms et des niveaux d’activité, exécution du regroupement et de la sum avec Java8. Si je fais le regroupement avec querydsl, je ne reçois pas les entrées de niveau unique. Inversement, dans ma solution, je dois effectuer plusieurs autres étapes.

Ce serait bien de savoir si cela est possible simplement en utilisant une requête.

Pure JPA & QueryDsl ne fonctionne qu’avec des entités. Vous pouvez donc créer une vue de firebase database qui regroupe les données que vous recherchez et les mapper vers une nouvelle entité, sur laquelle vous pouvez simplement effectuer une requête.

Une autre solution consiste à utiliser le support de requête jpa natif de QueryDsl. Voir http://www.querydsl.com/static/querydsl/3.6.1/reference/html/ch02.html la moitié inférieure. Vous auriez besoin du paragraphe le plus bas (Requête et projet dans DTO).

Cela revient à:

  • Générez des classes Q en pointant sur la firebase database (schéma) (je ne sais pas pourquoi c’est nécessaire, mais c’est dans la documentation)
  • Construire une requête à l’aide de la classe com.mysema.query.jpa.sql.JPASQLQuery
  • Assurez-vous de lister tous les champs de résultats nécessaires de la requête dans la méthode list
  • Créer une classe de bean dto sur laquelle vous pouvez projeter le résultat
  • Projeter le résultat dans la classe dto