Ich versuche, dynamische Abfragen mit JPA und Criteria API, aber ohne Metamodelle zu erstellen.LINKER JOIN mit AND-Operator unter Verwendung der Kriterien-API
Mit den Tabellen:
Foo:
ID
1
2
3
4
Bar:
ID FooID Number
1 2 44
2 2 55
3 3 55
Ich möchte alle Einheiten Foo abzurufen, wo keine passende Bar Nummer hat 44 (Erwartet Foo 1, 3, 4)
Die SQL sollte in etwa so aussehen:
select distinct *
from Foo foo0_
left join Bar bar0_ on foo0_.ID=bar0_.FooID and bar0_.Number=44
where bar0__.id is null;
Mein Code sieht in etwa wie folgt aus:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
Root<Foo> fooRoot = cq.from(Foo.class);
cq.select(fooRoot).distinct(true);
List<Predicate> allPredicates = new ArrayList<Predicate>();
List<Predicate> orPredicates = new ArrayList<Predicate>();
List<Predicate> andPredicates = new ArrayList<Predicate>();
andPredicates.add(cb.equal(fooRoot.join("bars", JoinType.LEFT).get("number"), 44));
andPredicates.add(cb.isNull(fooRoot.join("bars", JoinType.LEFT).get("ID")));
orPredicates.add(cb.and(andPredicates.toArray(new Predicate[andPredicates.size()])));
allPredicates.add(cb.or(orPredicates.toArray(newPredicate[orPredicates.size()])));
cq.where(allPredicates.toArray(new Predicate[allPredicates.size()]));
TypedQuery<Foo> query = em.createQuery(cq);
query.getResultList();
Aber das erzeugt diese SQL:
select distinct *
from Foo foo0_
left outer join Bar bar1_ on foo0_.id=bar1_.FooID
left outer join Bar bar2_ on foo0_.id=bar2_.FooID
where bar1_.Number=44 and (bar2_.id is null);
und gibt keine Foo.
Irgendwelche Ideen? Vielen Dank!
Ich benutze Hibernate JPA 2.0 so funktioniert leider barJoin.on (onCond) nicht. Die Prädikate _and_, _or_ und _all_ dienen zum Erstellen dynamischer Abfragen in verschiedenen Tabellen und mit unterschiedlichen Parametern. – Solver42
Geändert zu JPA 2.1 und verwendet Ihren Code aber qb zu cb geändert und ich bekomme AbstractMethodError: org.hibernate.ejb.criteria.path.ListAttributeJoin.on (Ljavax/Persistenz/Kriterien/Ausdruck;) Ljavax/Persistenz/Kriterien/Join; Ist qb ein QueryBuilder und brauche ich einen? Kann es in der JPA-Abhängigkeit nicht finden. – Solver42
Ja, Sie haben JPA 2.1 "ON" Bedingungen und ich "geändert zu JPA 2.1", weil ich es richtig machen will, aber ich kann es nicht zum Laufen bringen. Was ist qb? – Solver42