2010-10-20 10 views
7

Ho una domanda che penso dovrebbe essere abbastanza comune ma non riesco a trovare una risposta.hibernate @ManyToMany bidirezionale che richiama fetching

Ho 2 oggetti: Gruppo e Utente. Le mie lezioni sono qualcosa del tipo:

class Group 
{ 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<User> users; 
} 

class User 
{ 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<Group> groups; 
} 

Ora, quando cerco di ottenere un utente dal database che porta tutti i suoi gruppi e tutti i gruppi di portare tutti i suoi utenti e così via. Infine, sto ricevendo un'eccezione StackOverflow.

Come posso risolvere questo problema e mantenere la mia associazione bidirezionale e la possibilità di raggiungere gli oggetti negli elenchi?

risposta

8

si ottiene lo stesso problema se si fanno uno dei lati del vostro assocation bidirezionale la possedere lato dell'associazione mediante l'attributo mappedBy (che si dovrebbe usare in ogni caso)? Come questo:

@Entity public class Group { 
    ... 
    @ManyToMany(fetch = FetchType.EAGER, mappedBy="groups") 
    List<User> users; 
} 

@Entity public class User { 
    ... 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<Group> groups; 
} 

Update: non riesco a trovare alcuna prova che l'uso EAGER recupero su entrambi i lati di un'associazione bidirezionale è vietato e per quanto ne so, non v'è alcuna menzione di tale restrizione nella documentazione Hibernate e/o la specifica JPA.

realtà, secondo this comment da Emmanuel Bernard a (in qualche modo simile) problema:

LAZY o EAGER dovrebbe essere ortogonale ad una questione ciclo infinito nella base di codice. Hibernate sa come gestire i grafici ciclici

Per me, quanto sopra è abbastanza chiaro, Hibernate dovrebbe essere in grado di gestire la mappatura (come ho già detto in un commento) e sarei tentato di prendere in considerazione qualsiasi comportamento contraddittorio come bug.

Se è possibile fornire un test che consente di riprodurre il problema, il mio suggerimento sarebbe di aprire un problema.

+0

sì. succede la stessa cosa Posso capire che ha senso b/c in ibernazione ha bisogno di portare tutti gli oggetti della lista per ogni lista ed è un ciclo infinito. la mia domanda è se è possibile limitare la profondità che l'ibernazione porta oggetti (qualcosa come fetch_max_depth ma per molti a molti). – refaelos

+0

@Rafa In realtà, mi aspetto che Hibernate rilevi il ciclo e faccia la cosa giusta (ma non ho avuto il tempo di testarlo). D'altra parte, non posso dire questo caricando con entusiasmo entrambi i lati di un aspetto molti-a-molti come una buona idea. –

0

Hibernate funziona correttamente quando tenta di recuperare tutto ciò di cui ha bisogno. Gli oggetti di modellazione devono prendere in considerazione l'ibernazione, quindi non si verificano loop e eccezioni di stackoverflow.

Quello che ho fatto è rimuovere un lato della relazione. Puoi decidere se rimuovere quel lato o lasciarlo e definire l'altro lato come proprietario. Avrai anche bisogno di rimuovere la raccolta avida da quel lato.

Sarebbe bello se l'ibernazione potesse fornire un meccanismo per definire la profondità del recupero in relazioni molti-a-molti.

0

Si potrebbe voler impostare la proprietà "hibernate.max_fetch_depth" su qualcosa come 3 per limitare il richiamo ansioso.

Problemi correlati