2016-05-11 5 views
0

の有効な動作です:が、それは私は2つのエンティティが以下のようにマッピングされ、AとBを言わせて持って休止状態(JPQLクエリ、OneToMany)

public class A{ 
    ... 
    @OneToMany(mappedBy = "a", cascade = CascadeType.ALL) 
    Set<B> bs 
} 

public class B{ 
    ... 
    String someProp; 
    ... 
    @ManyToOne 
    @JoinColumn(name = "A_ID") 
    A a 
} 

Aのいくつかのエンティティインスタンスは、データベース内のBの2つの要素を持っています。

私は等の単純なクエリを実行する場合:

entityManager.createQuery("SELECT a FROM A a WHERE a.id = 1").getSingleResult(); 

をし、すべてが期待どおりに動作しますが、私はセットでのBの2つのインスタンスとインスタンスを得たが、私は、クエリを実行したとき:

Query query = entityManager.createQuery("SELECT a FROM A a JOIN FETCH a.bs b WHERE b.someProp= :somePropParam"); 
query.setParameter("somePropParam","somePropValue"); 
query.getResultList(); 

私はセットの中のBの1つの要素(私が求める要素)を持つAのインスタンスを得ました。

私は、クエリを変更:

entityManager.createQuery("SELECT b.a FROM B b JOIN b.a a WHERE b.someProp = :somePropParam.. more a conditions); 
//.... this query works. 

は、最初のクエリ負荷Bのすべてのインスタンスをべきではないのですか? Hibernateはそれらをすべてロードするために追加のクエリを実行するべきではありませんか?

+0

にBsの完全なコレクションを構築します返されたオブジェクトは、常に2つの要素を見つける必要があります。 –

+0

私はそれがAの "bs"セットの2要素を返すべきだと思うが、Aからの選択された '/ **カラムとb **/ から返されたように、ただ1つを返す。 .id = b.a_id b.someProp = 'someProperty''条件を満たしていない、追加のBテーブル行をロードする追加のクエリはありません。 'b.someProp =' someProperty'' –

+0

"期待される動作 "休止状態では確かに他の実装ではありません... –

答えて

1

これは正常な動作です。これは一般的な落とし穴です。メソッドgetSingleResultは、最初の行を返します。複数のBがある場合、結果セットには複数のエントリが含まれますが、最初のものだけを取得します。これはちょっと奇妙に思えるかもしれません。

しかし、それをsetMaxResult(1)と古典的なSQL結合を使用したプレーンなクエリとして見てください。それは同じ結果で終わるだろう。これは、あなたが熱心なフェッチを使用する場合、休止状態が子関係のために副選択を使用する理由です。

大量の子データが余分なクエリを持つ子を要求し、1対nの双方向マッピングを避けることを期待する場合。長期的にはしばしば問題につながる可能性があるので、親から子への関係には正当な理由があるはずです。

追加の例は次のように考えられます。 クエリとsetMaxResult(10)を使用します。あなたが親の10項目を取得することを保証する潜在的な結果セットのサイズは無制限です。だから、休止状態では、正しい量のデータを要求する機会はありません。これにより、大量のデータを必要とせずにフェッチすることができます。次の通りである

Query query = entityManager.createQuery("SELECT a FROM A a JOIN  FETCH a.bs b WHERE b.someProp= :somePropParam"); 
    query.setParameter("somePropParam","somePropValue"); 
    query.getResultList(); 

1

SQLのために生成

select /** columns from a and b **/ 
from A a inner join A b on a.id=b.a_id 
where b.someProp='someProperty' 

それは「それは私に指示(1行が返される)状況に応じて適切なSQL結果だはいfulfilingの1つのインスタンスがありますあなたが取得する条件はここにありますが、私は "JOIN FETCH a.bs"を持っていると思っていました。最初のクエリで要素が返されなくても、Hiberanteにすべての "bs"コレクションを強制的にロードさせました。私は、Hibernateが

SELECT b。* FROM B b WHERE b.a_id =(上記のクエリによって返されたID)のような追加クエリを実行すると考えました。

あなたがのコレクションフィールドにアクセスするとき(戻り値の型として持つ任意のクエリによって)返されたAは本当にそのコレクション内の2つの要素を持っている場合A.

+0

それはすべきです。それはしない –

関連する問題