Проблема при попытке построить запрос JPA из SQL - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть запрос, который отлично работает в SQL, но я не могу создать эквивалент в JPA.CriteriaBuilder «или» не выполняет «или».

Это таблицы ...

Table A

id : Long : primary key
b_id : Long : foreign key to id of Table B
c_id : Long : foreign key to id of Table C

Table B

id: Long : primary key
loc_id: Long 

Table C

id: Long : primary key
d_id : Long : foreign key to id of Table D

Table D

id: Long : primary key
loc_id: Long 

Этоданные в таблицах (в порядке перечисленных полей) ...

Table A:
1,  1,  null
2,  2,  null
3,  null,   1

Table B:
1,  5
2,  6

Table C:
1,  1

Table D:
1,  5

И мой запрос sql находит все записи в таблице A, где loc_id равен 5 в таблице B илиТаблица D через внешние ключи.(2 результата - идентификатор строки 1 и идентификатор строки 3)

select * from A 
LEFT JOIN B on B.id = a.b_id
LEFT JOIN C on C.id = a.c_id
LEFT JOIN D on D.id = c.d_id
WHERE B.loc_id = 5 or D.loc_id = 5

Однако я пытаюсь закодировать в JPA те же результаты.Я попробовал ниже, который создает 2 предиката, которые оба находят 1 запись, когда выполняются индивидуально, но когда я "или" их, это производит 0 записей.Как это может быть правильно?

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

Join<B, A> join1 = rt.join("b_id", JoinType.INNER);
Join<C, A> join2 = rt.join("c_id", JoinType.INNER);
Join<D, C> join3 = join2.join("d_id", JoinType.INNER);
predicates.add(cb.or(cb.equal(join1.get("loc_id"), 5), cb.equal(join3.get("loc_id"), 5)));

CriteriaQuery x = cq.select(rt).where(predicates.toArray(new Predicate[predicates.size()]));
Query q = em.createQuery(x);
List<A> = q.getResultList();

Все предложения с благодарностью приняты, спасибо ....

1 Ответ

0 голосов
/ 26 сентября 2019

Вот решение

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

Join<B, A> joinB = rt.join("b_id", JoinType.LEFT);
Join<C, A> joinC = rt.join("c_id", JoinType.LEFT);
Join<D, C> joinD = joinC.join("d_id", JoinType.LEFT);

Predicate bPredicate = cb.equal(joinB.get("loc_id"), 5);
Predicate dPredicate = cb.equal(joinD.get("loc_id"), 5);

Predicate predicate = cb.or(bPredicate, dPredicate);

CriteriaQuery<A> x = cq.select(rt).where(predicate);
TypedQuery<A> q = em.createQuery(x);

List<A> result = q.getResultList();
...