Domanda

Viene fornita la seguente struttura di classe:

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

class JobHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

Questa struttura di classe è accessibile sul db tramite JPA. Nel livello DAO posso scrivere query nella sintassi JPA.

Il problema: voglio un elenco con le voci Job e JobHistory per un determinato proprietario con un determinato ID e chi è l'ultimo in Jobhistory del lavoro (ordinato per assegnareData). Sembra abbastanza complicato, forse più semplice: dammi tutti i lavori e JobHistory dove il proprietario specificato è il proprietario effettivo del lavoro.

Aggiornamento: per chiarezza cambierò leggermente i nomi delle classi.

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

class JobOwnerHistory
{
    Date assignDate;
    User jobOwner;
}

class JobOwner 
{
    String name;
    String id;
}

Ogni Lavoro ha una cronologia dei suoi proprietari ordinata per assegnatoData . Al proprietario effettivo è stato assegnato l'ultimo lavoro (ovvero MAX (assegnatoData) ). Voglio trovare per ogni lavoro la voce JobOwnerHistory con MAX (assegnatoData) per un utente specifico User .

È stato utile?

Soluzione

Prova:

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

Se dovessi farlo in EclipseLink, lo cambierei leggermente:

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 differenza? Nella prima versione, stai restituendo due oggetti, quindi devi recuperarli da una lista o array di oggetti mentre nella seconda, il suggerimento per la query carica solo tutte le cronologie dei lavori da una (presumibilmente) pigra relazione uno-a-molti .

Non so se Hibernate abbia un equivalente di questo. Toplink Essentials no. Ma è una delle mie funzionalità preferite di EclipseLink.

Oh e ovviamente puoi (e probabilmente dovresti) usare una query con nome invece di una query ad hoc come ho fatto (dal momento che possono essere verificati durante la compilazione).

Altri suggerimenti

Ho trovato la seguente risposta per la query:

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 parte più importante nella query è la selezione secondaria con MAX(h2.assignDate) perché voglio ottenere il lavoro e la voce più recente nella cronologia dei proprietari .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top