2013-06-17 12 views
12

Próbuję utworzyć kryteria pobierania niektórych obiektów z 3 tabel (Associate, Update and Detail). Szczegół ma odniesienie do Associate and Update, a Update ma odniesienie do listy Szczegóły. Moim celem jest pobranie listy Aktualizacje, która ma co najmniej Szczegół z wartością pustą w określonym polu, z uwzględnieniem identyfikatora Associate. W JPQL było to łatwe, ale klient powiedział, że musi to być zakodowane za pomocą kryteriów.Kryteria WZP 2 z 3 tabelami

Moja JPQL było:

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

Próbowałem następujących, ale właśnie wrócił wszystkie aktualizacje bazy danych:

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

Czy ktoś może mi pomóc? Szukałem, ale nie mogę znaleźć żadnego przykładu z trzema elementami.

Odpowiedz

22

Każde łączenie przenosi użytkownika z lewego parametru typu do prawego. Łączenie details mojego kodu (druga linia) rozpoczyna się od fromUpdates, czyli Path<Update> i tworzy coś, co jest poza sceną, a także Path<Detail>. Z tego możesz budować inne sprzężenia. Wypróbuj to (kod nie testowany):

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

Pracował jak urok! Łączenie tych kryteriów doprowadzało mnie do szału, ale to bardzo pomogło! Dziękuję za wszystko :) –

1

Dla trzech tabel.

Konstruktor CriteriaBuilder = theEntityManager.getCriteriaBuilder(); Zapytanie CriteriaQuery1 = 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; 
} 

}

Powiązane problemy