2013-06-17 20 views
12

3つのテーブル(Associate、Update、Detail)からいくつかのオブジェクトを取得する基準を作成しようとしています。ディテールにはAssociateおよびUpdateへの参照があり、UpdateにはDetailsのリストへの参照があります。私の目的は、アソシエートIDが指定されている場合、指定されたフィールドに少なくともNull値のDetailを持つ更新リストを取得することです。 JPQLでは簡単に行うことができましたが、クライアントはこれを基準でコーディングする必要があると言いました。Criteria JPA 2 with 3 tables

マイJPQLだった:

public List<Update> getUpdates(long associateId) { 
    TypedQuery<Update> query = em.createQuery("select distinct u from Update u, Detail dt, Associate a " 
     + "where dt.update = u and dt.associate = a and a.associateId = :id and " 
     + "dt.ack_date is null", Update.class); 
    query.setParameter("id", associateId); 
    return query.getResultList(); 
} 

私は次のことを試してみましたが、それは単にデータベースにすべての更新を返さ:

public List<Update> getUpdates(long associateId) { 
    CriteriaBuilder builder = em.getCriteriaBuilder(); 
    CriteriaQuery<Update> query = builder.createQuery(Update.class); 

    Root<Update> fromUpdates = query.from(Update.class); 
    Root<Associate> fromAssociate = query.from(Associate.class); 
    Root<Detail> fromDetail = query.from(Detail.class); 

    Join<Detail, Associate> associateJoin = fromDetail.join("associate"); 
    Join<Detail, Update> updateJoin = fromDetail.join("update"); 

    TypedQuery<Update> typedQuery = em.createQuery(query 

      .select(fromUpdates) 
      .where(builder.and(
        builder.equal(fromAssociate.get("associateId"), associateId), 
        builder.equal(fromDetail.get("associate"), associateJoin), 
        builder.equal(fromDetail.get("update"), updateJoin), 
        builder.isNull(fromDetail.get("ack_date")) 
      )) 

      .orderBy(builder.asc(fromUpdates.get("updateId"))) 
      .distinct(true) 
    ); 

    return typedQuery.getResultList(); 
} 

誰も私を助けることができますか?私は検索しましたが、3つの実体を持つ例は見つかりませんでした。

答えて

22

それぞれの結合によって、leftish型のパラメータからrightish型のパラメータに移動します。したがって、私のコード(二行目)のdetailsは、fromUpdatesから始まり、Path<Update>で始まり、舞台裏ではPath<Detail>というものを作成します。それで、他の結合を構築することができます。試してください(コードはテストされていません)。

Root<Update> fromUpdates = query.from(Update.class); 
Join<Update, Detail> details = fromUpdates.join("details"); 
Join<Detail, Associate> associate = details.join("associate"); 
List<Predicate> conditions = new ArrayList(); 
conditions.add(builder.equal(associate.get("associateId"), associateId)); 
conditions.add(builder.isNull(details.get("ack_date"))); 

TypedQuery<Update> typedQuery = em.createQuery(query 
     .select(fromUpdates) 
     .where(conditions.toArray(new Predicate[] {})) 
     .orderBy(builder.asc(fromUpdates.get("updateId"))) 
     .distinct(true) 
); 
+3

が魅力のように働きました!これらの基準で私は狂っていましたが、これは多くの助けになりました!ありがとうございますperissf :) –

1

3つのテーブルが対象です。

CriteriaBuilder builder = theEntityManager.getCriteriaBuilder(); CriteriaQuery query1 = builder.createQuery(BasicMemberInfo.class);

Root<Table1> table1 = query1.from(Table1.class); 
    Root<Table2> table2 = query1.from(Table2.class); 
    Root<Table3> table3 = query1.from(Table3.class); 

    List<Predicate> conditions = new ArrayList(); 
    conditions.add(builder.equal(table3.get("Table1").get("memberId"), table1.get("memberId"))); 
    conditions.add(builder.equal(table2.get("tableid").get("memberId"), table1.get("memberId"))); 
    conditions.add(builder.equal(table2.get("indicator"), 'Y')); 
    conditions.add(builder.equal(table3.get("StatusCd"), "YES")); 

    TypedQuery<BasicCustInfo> typedQuery = theEntityManager.createQuery(
      query1.multiselect(table1.get("memberId"), table2.get("AcctId")) 
      .where(conditions.toArray(new Predicate[] {})) 
    ); 

    List<BasicMemberInfo> custList = typedQuery.getResultList(); 

パブリッククラスBasicMemberInfo {

String memberId; 
String AcctId; 

public BasicCustInfo() { 
    // TODO Auto-generated constructor stub 
} 

public BasicMemberInfo(BigDecimal memberId,String AcctId) { 
    this.memberId = memberId; 
    this.AcctId = AcctId; 
} 

public BigDecimal getmemberId() { 
    return memberId; 
} 
public void setmemberId(BigDecimal memberId) { 
    memberId = memberId; 
} 
public String getAcctId() { 
    return AcctId; 
} 
public void setAcctId(String AcctId) { 
    AcctId = AcctId; 
} 

}