Я пытаюсь построить динамические запросы с использованием JPA и API критериев, но без метамоделей.LEFT JOIN с оператором AND с использованием критериев API
С таблицами:
Foo:
ID
1
2
3
4
Bar:
ID FooID Number
1 2 44
2 2 55
3 3 55
Я хочу, чтобы получить все объекты Foo, где нет соответствия Бар не имеет номер 44. (Ожидая Foo 1, 3, 4)
SQL должен выглядеть примерно так:
select distinct *
from Foo foo0_
left join Bar bar0_ on foo0_.ID=bar0_.FooID and bar0_.Number=44
where bar0__.id is null;
Мой код выглядит примерно так:
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();
Но что порождает этот 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);
и не возвращает Foo.
Любые идеи? Спасибо!
Я использую Hibernate JPA 2.0, поэтому, к сожалению, barJoin.on (onCond) не работает. Предикаты _and_, _or_ и _all_ предназначены для построения динамических запросов в разных таблицах и с различными параметрами. – Solver42
Изменен на JPA 2.1 и использовал ваш код, но изменил qb на cb, и я получаю AbstractMethodError: org.hibernate.ejb.criteria.path.ListAttributeJoin.on (Ljavax/persistence/criteria/Expression;) Ljavax/persistence/criteria/join; Является ли qb QueryBuilder и мне нужен он? Невозможно найти его в зависимости от JPA. – Solver42
Да, вы отметили условия JPA 2.1 «ON», и я «Изменен для JPA 2.1», потому что я хочу сделать это правильно, но я не могу заставить его работать. Что такое qb? – Solver42