2014-11-03 27 views
6

Immagino sia facile, ma non riesco a capirlo.Come si costruisce un join inverso per una relazione unidirezionale?

Se ho entità Foo e Bar:

@Entity 
class Foo{ 
    @OneToMany 
    List<Bar> bars; 
} 

@Entity 
class Bar{ 
    @Column 
    int data; 
} 

e se voglio creare un (javax.persistence.criteria.Join<Foo, Bar>) oggetto Join, che posso fare in questo modo:

Root<Foo> root = ...; 
Join<Foo,Bar> join = root.join(Foo_.bars); 

Ma come posso fare un inverso unirsi

Join<Bar,Foo> inverseJoin = barRoot.join....()...? 

dal momento che non ho un campo java nella barra di classe che punta alla sua parentesi Foo t, è una relazione unidirezionale?

+0

Bene, la risposta ovvia è: non è una relazione unidirezionale se hai bisogno di un join inverso. Avete controllato utilizzando una relazione bidirezionale (aggiungendo '@ ManyToOne' a' Bar')? – mabi

+0

L'ho preso in considerazione, ma vorrei evitarlo, se possibile. –

+0

Probabilmente è necessario ricorrere a una query SQL raw, quindi. Non so come fare ciò che vuoi e IMHO non dovrebbe esserlo. – mabi

risposta

0

Se quello che ti serve è dato ad un Bar noto che è la sua appartenenza Foo questo si adatterebbe. La frase non sarà tradotta in SQL JOIN ma è semanticamente equivalente.

CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
CriteriaQuery<Foo> cq = cb.createQuery(Foo.class); 

Root<Foo> fooRoot = cq.from(Foo.class); 
Root<Bar> barRoot = cq.from(Bar.class); 

cq.select(fooRoot); 
cq.where(barRoot.in(fooRoot.get("bars"))); 
+0

** barRoot.in ** I mi chiedo se funziona con ** uguale ** anziché ** in ** –

+0

** fooRoot.get ("barre") ** è una raccolta. L'utilizzo di ** equal ** proverebbe a confrontare un singolo elemento (** barRoot **) in una raccolta, il che è sbagliato. –

+0

Ah, grazie, capito! –