Home » CriteriaAPI
Archiv der Kategorie: CriteriaAPI
Spezifische Feld-Auswahl bei CriteriaAPI Mehrfach-Joins
Folgendes Beispiel zeigt, wie man spezifische Felder aus einem Join für die Resultat-Tabelle selektiert, indem man eine eingene Empfängerklasse (hier Container) definiert und in CriteriaQuery.multiselect(..) die felder selektiert, die man eben in der Resultattabelle haben will.
Gelehrt hat mich dies diese Stackoverflow-Seite.
/** * Container, dem das spezifisch selektierten Feld übergeben wird */ public static class Container { private String orderList; private String businessCd; /** * CriteriaAPI übergibt an den Constructor. */ public Container(String orderList, String businessCd) { this.orderList = orderList; this.businessCd = businessCd; } public String getOrderList() { return orderList; } public String getBusinessCd() { return businessCd; } } Set<String> getWithCriteriApiExercise(UniqueId businessExecutionId) { CriteriaBuilder criteriaBuilder = daoProvider.getEntityManager().getCriteriaBuilder(); CriteriaQuery<Container> query = criteriaBuilder.createQuery(Container.class); // <-- !!! selbst definierte Empängerklasse (Container.class) Root<HpsBusiness> root = query.from(HpsBusiness.class); Join<HpsBusiness, HpsBusinessExec> joinBusiness = root.join(HpsBusiness._ATTR_businessExec, JoinType.INNER); //n:1 Join<HpsBusiness, HpsExcludedPos> joinExcludedPos = root.join(HpsBusiness._ATTR_excludedPosList, JoinType.INNER); //1:n query.multiselect(joinExcludedPos.get(HpsExcludedPos._ATTR_orderIdList), root.get(HpsBusiness._ATTR_businessCd)) // <-- !!! multiselect Methode benutzen!! .where(criteriaBuilder.and(criteriaBuilder.equal(joinBusiness.get(HpsBusinessExec._ATTR_id), businessExecutionId), criteriaBuilder.equal(joinExcludedPos.get(HpsExcludedPos._ATTR_reason), "deprecated"))); TypedQuery<Container> typedQuery = daoProvider.getEntityManager().createQuery(query); return typedQuery.getResultList().stream().map(c -> c.getOrderList() + "/" + c.getBusinessCd()).collect(Collectors.toSet()); // get the fields from Container }
Mehrfach-Join in CriteriaAPI
Beachte, dass bei den Joins sowohl in richtung n:1 als auch in Richtung 1:n (mit _ATTR_excludedPosList) referenziert wird!
Set<String> getBusinessTypesWithExclusions(UniqueId businessExecutionId) { CriteriaBuilder criteriaBuilder = daoProvider.getEntityManager().getCriteriaBuilder(); CriteriaQuery<HpsBusiness> query = criteriaBuilder.createQuery(HpsBusiness.class); Root<HpsBusiness> root = query.from(HpsBusiness.class); Join<HpsBusiness, HpsBusinessExec> joinBusiness = root.join(HpsBusiness._ATTR_businessExec, JoinType.INNER); // <-- n : 1 Join<HpsBusiness, HpsExcludedPos> joinExcludedPos = root.join(HpsBusiness._ATTR_excludedPosList, JoinType.INNER); // <-- 1 : n query.select(root).where(criteriaBuilder.and(criteriaBuilder.equal(joinBusiness.get(HpsBusinessExec._ATTR_id), businessExecutionId), criteriaBuilder.equal(joinExcludedPos.get(HpsExcludedPos._ATTR_exclusionReasonType), ExclusionReasonType.EXCLUDED.name()))); return daoProvider.getHpsBusinessDao().find(query).stream().map(HpsBusiness::getBusinessCd).collect(Collectors.toSet()); }
Criteria API: Join mit Filter auf beiden joined Tables
Der Knackpunkt is dieser:
Mit
Root<TabelleA> root = query.from(TabelleA.class)
wird die Ausgangstabelle (root) bezeichnet.
Mit
Join<TabelleA, TablleB> join = root.join(TabelleA.bRef);
wir HealthCheck hinzu ge-joined.
Wichig Referenzen (z.B. der Filter auf das Feld feldXY) müssen nun von join aus gehen:
join.get(TablleB.feldXY)
Oder die ganze Where-Clause:
.where(criteriaBuilder.equal(root.get(TabelleA.id), "id000001"), criteriaBuilder.like( join.get(TablleB.feldXY), "%gesuchterInhalt%"))
Ganze Beispiel
CriteriaBuilder criteriaBuilder = ippDaoProvider.getEntityManager().getCriteriaBuilder(); CriteriaQuery<TabelleA> query = criteriaBuilder.createQuery(TabelleA.class); Root<TabelleA> root = query.from(TabelleA.class); Join<TabelleA, TablleB> join = root.join(TabelleA.bRef); String healthCheckType = "BelowInvest"; query.select(root).where(criteriaBuilder.equal(root.get(TabelleA.id), "id000001"), criteriaBuilder.like( join.get(TablleB.feldXY), "%gesuchterInhalt%")); List<TabelleA> aList = ippDaoProvider.getHealthCheckExecutionDao().find(query);
Criteria API: Select where in / In list where clause
CriteriaBuilder cb = daoProvider.getEntityManager().getCriteriaBuilder(); CriteriaQuery<Employee2> criteriaQuery = cb.createQuery(Employee2.class); Root<Employee2> employee2Root = criteriaQuery.from(Employee2.class); criteriaQuery.select(employee2Root).where(employee2Root.get(Employee2._ATTR_gpn).in(gpns)); TypedQuery<Employee2> query = daoProvider.getEntityManager().createQuery(criteriaQuery); List<Employee2> employees = query.getResultList();