Résolution d'une requête JPA pour trouver la dernière entrée de la liste connectée

StackOverflow https://stackoverflow.com/questions/442488

  •  22-07-2019
  •  | 
  •  

Question

La structure de classe suivante est donnée:

class Job 
{
    String description;
    Collection<JobHistory> history;
}

class JobHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

Cette structure de classe est accessible sur la base de données via JPA. Dans la couche DAO, je peux écrire des requêtes en syntaxe JPA.

Le problème: je veux une liste avec les entrées Job et JobHistory pour un propriétaire donné avec un identifiant donné et qui est le dernier de la liste Jobhistory du travail (ordonné par assignDate). Cela semble assez compliqué, peut-être plus simple: donnez-moi tous les travaux et JobHistory où propriétaire spécifié est le propriétaire réel du travail.

Mise à jour: pour plus de clarté, je vais modifier légèrement les noms des classes.

class Job 
{
    String description;
    Collection<JobOwnerHistory> history;
}

class JobOwnerHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

Chaque travail a un historique de ses propriétaires trié par assignDate . Le propriétaire actuel a reçu le dernier travail attribué (c'est-à-dire MAX (assignDate) ). Je souhaite trouver pour chaque travail l'entrée JobOwnerHistory avec MAX (assignDate) pour un utilisateur spécifique Utilisateur .

Était-ce utile?

La solution

Essayez:

SELECT j, j.history FROM Job j JOIN User u WHERE u.name = :name

Si je devais le faire dans EclipseLink, je le modifierais légèrement:

public List<Job> getAllJobsForUser(String username) {
  List<Job> jobs = entityManager
    .createQuery("SELECT j FROM Job j JOIN User u WHERE u.name = :name")
    .setParameter("name", username)
    .setHint(QueryHints.BATCH, "j.history")
    .queryForList();
}

La différence? Dans la première version, vous renvoyez deux objets. Vous devez donc les récupérer à partir de tableaux ou de tableaux alors que dans la seconde, l'indicateur de requête ne charge que tous les historiques de travaux d'une relation (supposée) un-à-plusieurs. .

Je ne sais pas si Hibernate a un équivalent à cela. Toplink Essentials ne le fait pas. Mais c’est l’une de mes fonctionnalités préférées d’EclipseLink.

Oh, et évidemment vous pouvez (et devriez probablement) utiliser une requête nommée au lieu d’une requête ad hoc, comme je l’ai fait (car celles-ci peuvent être vérifiées lors de la construction).

Autres conseils

J'ai trouvé la réponse suivante pour la requête:

SELECT j, h FROM Job j JOIN j.history h JOIN h.jobOwner u
WHERE u.name = :name AND 
    (SELECT MAX(h2.assignDate) FROM Job j2 JOIN j2.history h2
     WHERE h2 member of j.history) = h.assignDate

La partie la plus importante de la requête est la sous-sélection avec MAX (h2.assignDate) car je souhaite obtenir le travail et la dernière entrée de l'historique propriétaire. .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top