Возможно ли как-то выполнить один из следующих запросов с помощью API JPA 2 Criteria?В основном, есть несколько шаблонов, которые используются профилями.Каждый пользователь в системе имеет любое количество профилей и два активных.Я хотел бы получить ВСЕ шаблоны и количество пользователей, которым принадлежат активные профили, которые его используют.
Альтернатива 1
SELECT t.id, count(p.id)
FROM template t
LEFT JOIN profile p ON p.template_id = t.id
LEFT JOIN users u ON (u.active_profile_id = p.id OR u.active_personal_profile_id = p.id)
GROUP BY t.id
Альтернатива 2
SELECT t.id, count(p.id)
FROM COMPETENCE.template t
LEFT JOIN COMPETENCE.profile p ON (p.template_id = t.id)
LEFT JOIN users u1 on u1.active_profile_id = p.id
LEFT JOIN users u2 on u2.active_personal_profile_id = p.id
GROUP BY t.id
Если я пропущу требование, чтобы получить все шаблоны, я могу просто использовать пользователя и профиль в качестве корней и следующиебыло бы достаточно:
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<User> from = cq.from(User.class);
Root<Profile> from2 = cq.from(Profile.class);
Join<Profile, Template> join = from2.join(Profile_.template);
cq.where(cb.or(
cb.equal(from.get(User_.activeCompetenceProfile), from2),
cb.equal(from.get(User_.activePersonalProfile), from2)
));
cq.groupBy(join.get(Template_.id));
cq.multiselect(join.get(Template_.id), cb.count(from2.get(Profile_.id)));
List<Tuple> tuples = em.createQuery(cq).getResultList();
Но, чтобы получить все шаблоны, я считаю, что не могу использовать предложение WHERE, но необходимо внешнее соединение, как в первых запросах.Однако альтернатива 1 кажется невозможной, поскольку вы не можете установить конкретное предложение ON для объединений, а альтернатива 2 кажется невозможной, поскольку и пользователь, и шаблон должны быть корневыми одновременно.Чтобы получить все шаблоны, мне нужно использовать Template как root и соединить его с Profile.Это хорошо, но я не могу присоединиться к Профилю с Пользователем, поскольку параметр ON хранится в Пользователе, а не в Профиле.Насколько мне известно, вы не можете объединить таблицу с другим параметром, хранящимся во второй таблице.
Задача, конечно, может быть решена несколькими способами, такими как выполнение второго запроса с выбором всех шаблонов и объединение его срезультат первого запроса, но если бы это было возможно сделать за один запрос, это привело бы к созданию более чистого кода.