2013-06-17 44 views
12

Tôi đang cố tạo một tiêu chí để truy xuất một số đối tượng từ 3 bảng (Liên kết, Cập nhật và Chi tiết). Chi tiết có tham chiếu đến Liên kết và Cập nhật và Bản cập nhật có tham chiếu đến danh sách Chi tiết. Mục tiêu của tôi là lấy một danh sách các bản Cập Nhật có ít nhất một chi tiết có giá trị null trong một trường được chỉ định, cho một ID liên kết. Trong JPQL dễ thực hiện nhưng khách hàng nói rằng điều này phải được mã hóa với các tiêu chí.Tiêu chí JPA 2 với 3 bảng

JPQL của tôi là:

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(); 
} 

Tôi đã thử các sau đây, nhưng nó chỉ trả lại tất cả cập nhật trong cơ sở dữ liệu:

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(); 
} 

bất cứ ai có thể giúp tôi? Tôi đã tìm kiếm nhưng không thể tìm thấy bất kỳ ví dụ nào với 3 thực thể.

Trả lời

22

Mỗi tham gia sẽ đưa bạn từ thông số loại bên trái sang tham số phù hợp. Vì vậy, việc tham gia details mã của tôi (dòng thứ hai) bắt đầu từ fromUpdates, đó là một số Path<Update> và tạo ra thứ gì đó đằng sau hậu trường cũng là Path<Detail>. Từ đó, bạn có thể tạo các kết nối khác. Hãy thử điều này (mã không được kiểm tra):

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

Làm việc như một nét duyên dáng! Những tiêu chí này đã khiến tôi phát điên, nhưng điều này đã giúp ích rất nhiều! Cảm ơn bạn perissf :) –

1

Đối với ba bảng liên quan.

Tiêu chíBuilder 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(); 

public class 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; 
} 

}

Các vấn đề liên quan