2012-11-11 10 views
5

Voglio avere un'opzione nel mio livello di repository per le entrate di caricamento ansioso, quindi ho provato ad aggiungere un metodo che dovrebbe caricare un'entità domanda con tutte le relazioni, ma genera MultipleBagFetchException. Come posso risolvere questo? Sto usando Hibernate 4.16.MultipleBagFetchException gettato

@NamedQuery(name = Question.FIND_BY_ID_EAGER, query = "SELECT q FROM Question q LEFT JOIN FETCH q.answers LEFT JOIN FETCH q.categories LEFT JOIN FETCH q.feedback LEFT JOIN FETCH q.participant WHERE q.id = :id"), 

Come faccio ad avere un oggetto di domanda che inizialmente è caricato in modo pigro, ad essere ansiosi caricato con tutti i rapporti?

risposta

23

Questo è un problema piuttosto brutto in Hibernate e in realtà ORM in generale.

Quello che succede è che i molti join (di recupero) causano la creazione di un prodotto cartesiano piuttosto grande. Per sempre altri unisco nuove colonne e nuove righe appaiono nel risultato, portando ad un risultato 'quadrato' (abbastanza) grande.

Hibernate ha bisogno di distillare un grafico da questa tabella, ma non è abbastanza intelligente da abbinare le colonne giuste alle entità giuste.

E.g.

supponiamo di avere il risultato

A B C 
A B D 

che deve diventare:

A 
| 
B 
/\ 
C D 

Hibernate poteva dedurre dalle chiavi primarie e qualche magia di codifica, che cosa il grafico deve essere, ma in pratica ha bisogno di aiuto esplicito per tirarlo fuori.

Un modo per farlo è specificando lo specifico Hibernate o lo standard JPA @OrderColumn sulle relazioni.

E.g.

@Entity 
public class Question { 


    @ManyToMany 
    @JoinTable(
     name = "question_to_answer", 
     joinColumns = @JoinColumn(name = "question_id"), 
     inverseJoinColumns = @JoinColumn(name = "answer_id") 
    ) 
    @IndexColumn(name = "answer_order") 
    private List<Answer> answers; 

    // ... 
} 

In questo esempio sto utilizzando una tabella di aderire, con una colonna in più answer_order. Tramite questa colonna, che ha un numero sequenziale unico per ogni relazione domanda/risposta, Hibernate può distinguere le voci nella tabella dei risultati e creare il grafico oggetto richiesto.

Una nota btw, se riguarda più di alcune entità, l'utilizzo di così tanti join desiderosi può potenzialmente portare a un set di risultati molto più ampio di quanto si possa pensare in base al numero di entità coinvolte.

Ulteriori approfondimenti:

+0

Va notato che '@ IndexColumn' è ormai deprecato (attualmente usando Hibernate 5.2.4.Final) – JRSofty

Problemi correlati