2012-03-07 7 views
15

私はhibernateと一緒に作業しています。私は自分のオブジェクトのすべての子をフェッチするhqlクエリを作成する際に問題を抱えています。 例: Object Userには、CarsのリストとFriendsのリストがあります。 u.cars u.id =をフェッチ参加uは左ユーザーから
Hibernateで複数の子をフェッチする方法は?

は、私は次のクエリを使用することになり、彼の車を持つユーザーを取得するには?

これは正常に動作しますので、私は彼の車とし、次のクエリと彼の友人とユーザーを取得するのは簡単だろうと思った:uはu.carsをフェッチ参加左ユーザーから
u.friendsどこをフェッチ左結合しましたu.id =?

しかし、これは私に次のエラー与える:
HibernateExceptionで:同時に複数の袋今

を取得することはできませんが、私の質問です:休止状態で複数の子を取り出すための正しい方法は何ですか?

+0

重複:http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags。休止状態の使用:@LazyCollection(LazyCollectionOption.FALSE) – willome

答えて

10

子コレクションの多くは1つのバッグ(つまりリストとして宣言)でなければなりません。他のコレクションをSetとして宣言すると、それが機能します。

このようなフェッチ結合を実行すると、列のカーテシアンが生成されることに注意してください。両方のコレクションに100要素がある場合、そのようなクエリはデータベースから10,000行を取り出します。 1つのコレクションを取り出す最初のクエリと、もう1つを取り出す2番目のクエリを実行するほうが効率的な場合があります(取得する行数を200に減らす)。これはまた、あなたが持っている問題を回避する方法です:

select u from User u left join fetch u.cars where u.id = :id; 
select u from User u left join fetch u.friends where u.id = :id; 
+1

ニース知っている。 scondクエリが実際に最初のクエリによってロードされた同じユーザーエンティティ上のfriendsコレクションに移入することは直感的には明らかではありません。しかし、それは(キャッシュのおかげで)動作する方法です! –

+1

この2つのHSQLクエリを '@ NamedQuery'の中に書くことはできますか? – MyTitle

+0

@MyTitle:いいえ。名前付きクエリは2つではなく1つのクエリです。 –

6

あなただけのコレクション/一覧(袋)問題を打ちます。

ここには、これに関するHibernateの公式の "issue"へのリンクがあります:https://hibernate.atlassian.net/browse/HHH-1718。ご覧のように、2006年にオープンしていて、まだオープンしています。

JB Nizetが提案していることに加えて、あなたのモデルにコレクションやリストの代わりにSetを使うことをお勧めします。そうでない場合は、Collection/ListをFetchMode.SUBSELECTとして指定することもできます。 (実装するのは面倒です)、@ OneToMany/@ ManyToManyで@IndexColumnを使用することができます。

このブログの記事では、実装するソリューションにご案内します。つまりhttp://jroller.com/eyallupu/entry/hibernate_exception_simultaneously_fetch_multiple

は、あなたが回避策を除いて、何をしたいのかを正確に行うには解決策はありません。

希望すると便利です。

編集:それはアプリケーション/データベースに対して重すぎるだろうとタイポ

0

ない可能性、 あなたは2つの別々の基準を作成し、個別にデータを取得する必要があります。

Cat cat = sess.createCriteria(Cat.class) 
       .add(Restrictions.like("name", "F%")) 
       .uniqueResult(); 

List kitten = sess.createCriteria(Kitten.class) 
        .add(Restrictions.eq("cat", cat)) 
        .createCriteria("kittens") 
        .add(Restrictions.like("name", "F%")) 
        .list(); 

List mate = sess.createCriteria(Mate.class) 
       .add(Restrictions.eq("cat", cat)) 
       .createCriteria("mate") 
       .add(Restrictions.like("name", "F%")) 
       .list(); 
関連する問題