2012-11-11 13 views
5

私はリポジトリレイヤーに熱心な負荷のエンティティにオプションを持ちたいので、質問エンティティをすべてのリレーションシップで読み込めるようにメソッドを追加しようとしましたが、MultipleBagFetchExceptionがスローされます。これをどうすれば解決できますか?私はHibernate 4.16を使用しています。MultipleBagFetchExceptionがスローされました

@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"), 

最初に遅延ロードされた質問オブジェクトをすべてのリレーションで読み込むにはどうすればよいですか?

答えて

23

これは、Hibernateと実際にORMではかなり厄介な問題です。

何が起こるかは、多くの(フェッチ)結合によって、かなり大きなデカルト積が生成されるということです。つまり、他の新しい列を結合して新しい行を結果に表示すると、(かなり)大きな「正方形」の結果になります。

Hibernateはこのテーブルからグラフを抽出する必要がありますが、右側の列と右側のエンティティを一致させるほどスマートではありません。

など。私たちはなる必要が結果

A B C 
A B D 

があるとし

A 
| 
B 
/\ 
C D 
Hibernateはなく、実際には、グラフがでなければならないものを主キーといくつかのエンコーディングの魔法から差し引くことができ

それこれを取り除くためには明示的な助けが必要です。

これを行う1つの方法は、関係にHibernate固有の@IndexColumnまたはJPA標準@OrderColumnを指定することです。

など。

@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; 

    // ... 
} 

この例では、追加の列answer_orderを使用して結合テーブルを使用しています。質問/回答関係ごとに固有の連続番号を持つこの列を介して、Hibernateは結果テーブルの項目を区別し、必要なオブジェクトグラフを作成することができます。

いくつかのエンティティより多くの懸念がある場合、非常に多くの熱心な結合を使用すると、関連するエンティティの数に基づいて考えられるよりも大きな結果セットにつながる可能性があります。

さらに読書:

+0

'@のIndexColumn'は今(現在は休止状態5.2.4.Finalを使用して)は推奨されていることに留意しなければなりません – JRSofty

関連する問題