2011-11-10 7 views
1

みんな、以下の問題で私を助けてください。複数のバッグを取得できません:なぜ@IndexColumnが間違った結果を返しますか?

親団体に2つのリストがあるため、有名な「複数のバッグを同時に取り込めません」というエラーが発生しました。コードの傷は次のとおりです。

class Manager{ 
    @OneToMany(cascade = CascadeType.ALL) 
    @Fetch(FetchMode.JOIN) 
    @IndexColumn(name = "id") 
    private List<Action> actions; 

    @OneToMany(cascade = CascadeType.ALL) 
    @Fetch(FetchMode.JOIN) 
    @IndexColumn(name = "id") 
    private List<Activity> activities; 
(...) 
} 

マッピングは単方向です。

OK、私はそれを修正するためにIndexColumn注釈を使うことができます。私はそれを実装しました。あなたが見ているように、今は言及されていない例外はありません。しかし、問題は、今私がdbからすべてのマネージャーを取得したい場合、私は実際に存在する多くのマネージャーインスタンスを受け取ることです!

たとえば、各コレクションに1つのマネージャインスタンスと3つの子インスタンスがある場合は、9つのマネージャインスタンス。私はこれがなぜ起こるのか理解できます:

select ... from Manager this_ 
left outer join manager_action actions3_ on this_.id=actions3_.Manager_id 
left outer join Action action4_ on actions3_.actions_id=action4_.id 
left outer join Manager_Activity activities5_ on this_.id=activities5_.Manager_id 
left outer join Activity activity6_ on activities5_.activities_id=activity6_.id 

...これは本当に1つ以上の行をフェッチします。

これはどうしてですか? どうすれば修正できますか?

答えて

0

Hibernateはデカルト積を生成し、この場合重複排除はしません。このようなデカルト製品(3アクション* 3アクティビティ= 9行)は、リストではなくセットでのみ機能します。

2つのセットでも、この種のデカルト製品を避けるべきです。それについて考えてみましょう:100アクションと100アクティビティを持つマネージャーを1つだけ取得すると、データベースから10,000行が取得されます。そのアクション(100行)その活動と同じマネージャをフェッチ

  • 1(100行)
  • になるだろうとマネージャをフェッチ

    • 1:あなたは、おそらく2つのクエリを作成する必要があります10,000行ではなく200行だけです。また、アクティビティがセッションの同じManagerインスタンスにアタッチされるため、結果は同じになります。また、重複の問題も回避できます。

    +0

    ありがとう、JB Nizet! (1)しかし、どのような場合にHibernateが複数の行を正しい方法で処理できるかを説明できますか? (2)そして2番目の質問は、なぜ追加の行が追加のクエリより悪いと思いますか? – KutaBeach

    関連する問題