Проблема с множественными объединениями критериев jpa - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть таблица с 2 внешними ключами.Мне нужно создать запрос, который агрегирует результаты, которые используют оба внешних ключа.

т.е. таблица A "b_id" является внешним ключом для таблицы B "id", таблица A "c_id" является внешним ключом для таблицы C«id» 123 - это переменная id, которую я хочу запросить

Я могу успешно найти 1 результат, где id = 123, который присоединяется к таблице B следующим образом ...

EntityManager em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root<A> rt = cq.from(A.class);
List<Predicate> predList = new ArrayList<>();

Join<A, B> joinB = rt.join("b_id", JoinType.INNER);
Predicate p1 = cb.equal(joinB.get("id"),123);
predList.add(p1); 

cq.select(rt).where(predList.toArray(new Predicate[predList.size()]));
Query q = em.createQuery(cq);

...и я могу успешно найти 1 результат, где id = 123, который присоединяется к таблице C следующим образом ...

EntityManager em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root<A> rt = cq.from(A.class);
List<Predicate> predList = new ArrayList<>();

Join<A, C> joinC = rt.join("c_id", JoinType.INNER);
Predicate p1 = cb.equal(joinC.get("id"),123);
predList.add(p1); 

cq.select(rt).where(predList.toArray(new Predicate[predList.size()]));
Query q = em.createQuery(cq);

Так что я подумал получить оба результата в одном запросе "или" 2 предиката какниже, но это не работает?

EntityManager em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root<A> rt = cq.from(A.class);

List<Predicate> predList = new ArrayList<>();

Join<A, B> joinB = rt.join("b_id", JoinType.INNER);
Join<A, C> joinC = rt.join("c_id", JoinType.INNER);
Predicate p1 = cb.equal(joinB.get("id"),123);
Predicate p2 = cb.equal(joinC.get("id"),123);
predList.add(cb.or(p1, p2)); 

cq.select(rt).where(predList.toArray(new Predicate[predList.size()]));
Query q = em.createQuery(cq);

Что я здесь не так делаю, пожалуйста?спасибо ...

SQL, сгенерированный этим запросом, когда я применяю изменение, предложенное Twister, (без лишних полей)

SELECT t1.my_id FROM e t3, d t2, a t1, c t0 WHERE (((t1.my_id = 123) OR (t3.my_id = 123)) AND (((t0.id = t1.id) AND (t2.id = t0.id)) AND (t3.id = t2._id)))

1 Ответ

0 голосов
/ 21 сентября 2018

Функция, в которой (Предикат ... ограничения) CriteriaQuery использует оператор "И" для всех ограничений.

Если вы хотите использовать «или» для 2 предикатов, вы можете попробовать это:

cq.select(rt).where(cb.or(predList.toArray(new Predicate[0])));
...