2012-04-02 11 views
4

私は基準クエリでリスト属性を取得する際にJPA 2で予期しない動作と思われるものを観察しています。JPA基準フェッチリスト内のクエリ重複した値

次のように私のクエリは(それの抽出物)である:

CriteriaBuilder b = em.getCriteriaBuilder(); 
CriteriaQuery<MainObject> c = b.createQuery(MainObject.class); 
Root<MainObject> root = c.from(MainObject.class); 
Join<MainObject, FirstFetch> firstFetch = (Join<MainObject, FirstFetch>) root.fetch(MainObject_.firstFetch); 
firstFetch.fetch(FirstFetch_.secondFetch); //secondFetch is a list 
c.select(root).distinct(true); 

(それでは、私は、オブジェクトのプロパティのプロパティとしてリストを取得していましょう。)

事クエリが複数の結果を返す場合、secondFetch値は行が返される回数だけ複製されます。各firstFetchはちょうど1 secondFetchを持っているが、代わりにNを持っている必要があります。 このケースで私が見る唯一の特殊性は、すべてです。メインオブジェクトは、同じFirstFetchインスタンスを持っています。 私の推測では、結合が正常に行われていると推測されますが、JPAはのsecondFetchオブジェクトをfirstFetchsのそれぞれに割り当てられません。

マッピングは、the'reは多かれ少なかれ、この

@Entity 
@Table(name="mainobject") 
public class MainObject{ 
    //... 
    private FirstFetch firstFetch; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="mainObject_column") 
    public FirstFetch getFirstFetch() { 
    return firstFetch; 
    } 
} 

@Entity 
@Table(name="firstFetch") 
public class FirstFetch{ 
    //... 
    private List<SecondFetch> secondFetch; 

    @OneToMany(mappedBy="secondFetch") 
    public List<SecondFetch> getSecondFetch() { 
     return secondFetch; 
    } 
} 

&のような最終的に私が探していた

@Entity 
@Table(name="secondFetch") 
public class SecondFetch { 
    //.... 
    private FirstFetch firstFetch; //bidirectional 

    @ManyToOne 
    @JoinColumn(name="column") 
    public FirstFetch getFirstFetch() { 
     return firstFetch; 
    } 
} 

あまりにも特別なことではないはずですいくつかの種類の別の適用する文フェッチにどれも(とにかく「パッチ」されているだろう...)

は私が

Set<SecondFetch> 

ため

List<SecondFetch> 

を変更する場合、私は感謝に期待される結果を得ることができますありません'キーを設定しているので、これはJPAのリストに間違いがあると感じます。

でも、私は専門家ではないので、私はperfectllyマッピングまたはクエリ内のいくつかのミスを作ることができます。 これを解消するのに手伝っていただきたいと思います。おかげさまで

+0

どのJPAプロバイダをお使いですか?バグかもしれない。 – James

+0

私はJBoss 6.1.0のデフォルトのプロバイダを使用しています。これは、間違っていない場合、Hibernate 3.6.6 Finalになります。 –

+0

私はまったく同じ問題を抱えています。 私はこのような(秒)リストをフェッチするために基準APIを使用しています: d.fetch(FirstFetch_.secondFetch、JoinType.LEFT); – Jens

答えて

3

私は、クエリを行うにはJPA基準APIを使用していたものの、まったく同じ問題を抱えていました。

は、いくつかの研究の後、私はあなたがすでに言及した解決策を見つけました(しかし、あなたが基準のAPIを使用していないため、利用できませんでした):distinctを使用します。 JPA基準に

それは次のようになります。

CriteriaQuery<FirstFetch> query = cb.createQuery(FirstFetch.class); 
Root<AbschnittC> root = query.from(FirstFetch.class); 
root.fetch(FirstFetch_.secondFetch, JoinType.LEFT); 
query.distinct(true); 

結果セットがsecondFetchリスト内のオブジェクトの量に乗じたquery.distinct(true);を使用しません。

Hibernateには、DISTINCT_ROOT_ENTITYのようなものがあります。これは、単に別のクエリを設定するよりも適切です。しかし、私はこれ以上調べなかった。私はJPAプロバイダとしてHibernateも使用しています。 JPAでqueryを別に設定すると、Hibernates DISTINCT_ROOT_ENTITYと同じコードを使用することになりますか?

+0

フィードバックをいただきありがとうございます。このDISTINCT_ROOT_ENTITYを見て、できるだけ早く更新します。 –

+0

あなたの例では1つのfetch()しか行いません。私はそれが上記のものと同じだとは思わない。 – rakslice