Frage

Nach der Klassenstruktur gegeben:

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

class JobHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

Diese Klasse-Struktur ist auf der db über JPA zugänglich. In der DAO-Schicht kann ich Abfragen in JPA Syntax schreiben.

Das Problem: Ich möchte eine Liste mit Job und JobHistory Einträgen für einen bestimmten Besitzer mit angegebener ID und wer ist die letzte in der Jobhistory des Auftrags (geordnet nach assignDate). Klingt ziemlich kompliziert, vielleicht einfacher. Gib mir alle Aufträge und JobHistory wo angegebenen Besitzer der tatsächliche Besitzer des Auftrags ist

Update:. für Klarheit werde ich leicht die Namen der Klassen ändern

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

class JobOwnerHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

Jeder Job hat eine Geschichte von seinen Besitzern von assignDate sortiert. Der eigentliche Eigentümer bekam den Job zuletzt zugewiesen (das heißt MAX(assignDate)). Ich mag für jeden Auftrag des JobOwnerHistory Eintrag mit MAX(assignDate) für einen bestimmten Benutzer User finden.

War es hilfreich?

Lösung

Versuchen:

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

Wenn ich dies in Eclipse tun, würde ich es leicht ändern:

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();
}

Der Unterschied? In der ersten Version sind Sie zwei Objekte zurückkehren, so dass Sie sie aus einer Liste abrufen oder Objekt-Arrays während in den zweiten, der Abfrage-Hinweis lädt einfach alle Auftragsprotokolle von einer (vermutlich) lazyy einer Eins-zu-viele-Beziehung .

Ich weiß nicht, ob Hibernate ein Äquivalent zu diesem hat. Toplink Essentials-nicht. Aber es ist eine meiner Lieblings-Features von Eclipse.

Oh, und natürlich können Sie (und wahrscheinlich sollen) eine benannte Abfrage statt einer Ad-hoc-Abfrage verwenden, wie ich getan habe (da diese während des Build überprüft werden).

Andere Tipps

Ich fand die folgende Antwort für die Abfrage:

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

Der wichtigste Teil in der Abfrage ist die subselect mit MAX(h2.assignDate) , weil ich will den Job bekommen und den neuesten Eintrag in der Eigentümer-Geschichte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top