2012-10-02 17 views
9

Ci sono tre tabelle modellati come tre entità:JPA 3 vie aderire annotazione

@Entity 
@Table(name="event") 
public class Event { 
    public Long datetime; 
    public String name; 
    public Long processId; 
} 

@Entity 
@Table(name="process") 
public class Process { 
    public Long Id; 
    public Long sequence; 
    public Name name; 
} 

@Entity 
@Table(name="operation") 
public class Operation { 
    public Long Id; 
    public Long datetime; 
    public Long sequence; 
} 

Qualunque singolo record unico processo funzionamento sequenza si ottiene l'SQL che ha un vincolo a 3 vie join:

SELECT * 
FROM event e, process p, operation q 
WHERE e.processId = p.id 
    AND e.datetime = q.datetime 
    AND p.sequence = q.sequence 

di attuare tale in APP, devo fare un elenco di operazioni, che sarebbe esplicitamente ridotta a un singolo record thro il p.sequence uguaglianza JQPL = q.sequence

@Entity 
@Table(name="event") 
public class Event { 
    public Long datetime; 
    public String name; 
    public Long processId; 
    @OneToOne 
    @JoinColumn(
    name = "processId", referencedColumnName="id", 
    insertable=false, updatable=false) 
    private Process process; 

    @OneToMany 
    @JoinColumn(
    name = "datetime", referencedColumnName="datetime", 
    insertable=false, updatable=false) 
    private List<Operation> operations; 
} 

Qualora il JPQL specifica il 3 ° transitiva join vincolo:

SELECT e FROM Event e 
INNER JOIN FETCH e.process p 
INNER JOIN FETCH e.operations q 
WHERE p.sequence = q.sequence 

Tuttavia, voglio tutti i tre vincoli di essere modellati all'interno dell'entità POJO. Non dovrebbe esserci modo di utilizzare le annotazioni JPA da solo a un join a tre vie? Come le seguenti entità pseudo-codice illustra:

@Entity 
@Table(name="event") 
public class Event { 
    public Long datetime; 
    public String name; 
    public Long processId; 
    @OneToOne 
    @JoinColumn(
    name = "processId", referencedColumnName="id", 
    insertable=false, updatable=false) 
    private Process process; 

    @OneToOne 
    @JoinColumn(
    name = "datetime", referencedColumnName="datetime", 
    insertable=false, updatable=false) 
    @JoinColumn(
    name = "process.sequence", referencedColumnName="sequence", 
    insertable=false, updatable=false) 
    private Operation operations; 
} 

in modo che non sarebbe stato necessario specificare transitiva-join vincolo nel JPQL

SELECT e FROM Event e 
INNER JOIN FETCH e.process p 
INNER JOIN FETCH e.operations q 

Come faccio a modello di un transitiva join utilizzando le annotazioni JPA?

+0

BTW, ho lasciato fuori le annotazioni JAXB. L'evento deve assolutamente essere il tag radice XML. Pertanto, l'entità viene modellata utilizzando il POJO evento. L'entità Event viene utilizzata direttamente come XML DTO tramite JAXB. Vale a dire, non dovresti suggerire di utilizzare un altro POJO come root. –

+0

Non sono sicuro al 100% su quale sia il problema ... se si specifica la clausola ON dei join, non risolve il problema? – slambeth

risposta

2

Sembra che tu stia cercando di modellare una query, invece dei tuoi dati. Dovresti modellare i dati correttamente, quindi scrivere la tua richiesta.

Lei sembra avere

Evento

  • processo
  • ManyToOne (ProcessID)

processo

  • eventi - OneToMany
  • operazioni - OneToMany

funzionamento

  • processo - ManyToOne (sequenza) (questo è un po 'strano, come sequenza non è l'ID, questo è al di fuori delle specifiche dell'APP, ma alcuni JPA provider può sostenerlo)

per interrogare tutte le operazioni per un evento, si potrebbe usare,

Select o from Operation o join o.process p join p.events e where e.datetime = o.datetime 

Per ottenere tutto l'oggetto indietro utilizzare,

Select o, p, e from Operation o join o.process p join p.events e where e.datetime = o.datetime 

Se si ha realmente bisogno di modellare la query come un rapporto, questo è al di fuori delle specifiche JPA, ma alcuni provider JPA può sostenerlo. In EclipseLink è possibile utilizzare un DescriptorCustomizer per configurare qualsiasi relazione per l'utilizzo di qualsiasi criterio di espressione o di proprietà di SQL.

+4

Vi prego di accettare le mie scuse - ma potreste ristrutturare la vostra risposta per rispondere alla mia domanda piuttosto che consigliarmi come liberare la mia vita dai detriti che le persone mi stanno gettando addosso? Grazie. –

1

I suoi pseudo-mappature sono quasi la soluzione corretta, non vi resta che raggruppare due @JoinColumn s in un @JoinColumns:

@OneToOne 
@JoinColumns({ 
    @JoinColumn(
    name = "datetime", referencedColumnName="datetime", 
    insertable=false, updatable=false), 
    @JoinColumn(
    name = "sequence", referencedColumnName="sequence", 
    insertable=false, updatable=false) 
}) 
private Operation operations; 
Problemi correlati