2016-04-19 12 views
0

要素のリストを含むエンティティがあります。これらの要素の属性を検索したいと思います。この制約は、 "and"で接続する必要があります。これらの単純な例を参照してください。JPA CriteriaBuilderは、コレクションに特定の属性を持つ要素を持つエンティティを見つけます。

@Entity 
public class Parent { 

    @Column 
    @Enumerated(EnumType.STRING) 
    private City city; 

    @OneToMany(...) 
    private List<Children> childrens; 
} 

@Entity 
public class Children { 

    @Column 
    @Enumerated(EnumType.STRING) 
    private School school; 

    @Column 
    private Integer yearInSchool; 

}  

は、今私は、ある街で両親を見つけたい、私は、検索を取得したいクラス/年6である学校の子供たち「AwesomeSchool」と「BigCity」を言うことができます結果はCriteriaBuilderを使用した場合のみです。

は、これまでのところ私が得た: これはどちらかである子供たちとすべての親を返します - - 私は、リスト属性 にget("school")を呼び出すことはできませんように見える:

final CriteriaBuilder c = getCriteriaBuilder(); 
final CriteriaQuery<Parent> query = c.createQuery(Parent.class); 
final Root<Parent> r = query.from(Parent.class); 
query.select(r) 
     .where(c.and(c.equal(r.get("city"), City.BigCity)), 
       c.equal(r.get("childrens").get("school"), School.AwesomeSchool), 
       c.equal(r.get("childrens").get("yearInSchool"), 6)); 

は、残念ながらここで2つの問題があります「AwesomeSchool」で6年間、または学校で6年間です。

お願いします。私は結合を使用することを考えましたが、同じ質問があります:どのようにして、両方の属性(schoolとyearInSchool)を同時に満たす必要があると考えられるように結合の部分をwhereと定義できますか? 子どもが1つの条件を満たしているオブジェクトのクエリに関する同様の記事を見つけましたが、ここでは子供は同時に2つの条件を満たさなければなりません。

更新1 たとえば、一人の子供の「学校」、私はこれまで、述語に関する取得:

Predicate predicate = r.join("childrens").get("school").in(School.AwesomeSchool) 

は、どのように私は主張するには、この参加オブジェクトが第二のフィルタ条件にもある再利用することができますか?

+0

あなたが現在それを持っているとして、あなたは一度に子供に一つの条件を満たしますので、子供1つの条件を満たすようにしてもよいが、子2他の条件。同じ子が両方の条件を満たすようにしたいので、2番目と3番目のwhere節で結合を使用して結合したオブジェクトを使用する必要があります。クライテリアパートを実行する前に、それをプレーンなJPQLとして書く価値があります。 –

+0

こんにちはNeil、ご意見ありがとうございます。はい、あなたは完全に私の問題を抱えています。 1つの条件の結合で質問を更新しました。このオブジェクトを再利用して2番目の条件をフィルタリングするにはどうすればよいですか? –

答えて

1

JOINが必要です。次に、WHERE句を作成するときに結合を作成するときに取得したJOINオブジェクトを使用します。

Join childrenJoin = r.join("childrens"); 

query.where(c.and(c.equal(r.get("city"), City.BigCity)), 
       c.equal(childrenJoin.get("school"), School.AwesomeSchool), 
       c.equal(childrenJoin.get("yearInSchool"), 6)); 

はおそらく、あなたはあなたのJPQLがあることを意味:

SELECT p FROM Parent p JOIN p.childrens c 
WHERE p.city = :theCity AND c.school = :theSchool AND c.yearInSchool = 6 
+0

ありがとうございます。私はこれを試してみる。しかし、私がこれを読んだとき、この親に2人の子供、「AwesomeSchool」とクラス10、そして「SomeotherSchool」と第6クラスに2人の子供がいれば、これもParent "P"を返さないでしょうか?私が親を見ると、条件が満たされます:親Pには、AwesomeSchoolの子供と6歳の子供がいます。 –

関連する問題