У меня есть следующий родной SQL запрос, который я пытаюсь преобразовать критерии JPA:Преобразование SQL левое внешнее соединение запроса к JPA Критерии
select et.* from t_empl_tx et, t_dept d
where et.assigned_dept = d.dept (+)
and et.employee_id = :employee_id
and (et.start_date >= d.dept_est_date and
et.start_date <= d.dept_close_date or
et.start_date is null or
d.dept is null)
(Заметим, что (+) примерно эквивалентно левого внешнего присоединяйтесь в этом случае. Да, я знаю, что это означает OPTIONAL table и т. д. и т. д.).
Вот моя попытка кода:
EntityManager entityManager = getEntityManager();
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<EmployeeTransaction> criteriaQuery = criteriaBuilder.createQuery(EmployeeTransaction.class);
Root<EmployeeTransaction> root = criteriaQuery.from(EmployeeTransaction.class);
// this line bombs!
Join<EmployeeTransaction, Department> join =
root.join(EmployeeTransaction_.assignedDepartment).join(Department_.id).join(DepartmentCompositeId_.department, JoinType.LEFT);
List<Predicate> predicates = new ArrayList<>();
predicates.add(criteriaBuilder.equal(root.get(EmployeeTransaction_.id).get(EmployeeTransactionCompositeId_.employeeId), employeeId));
predicates.add(criteriaBuilder.or(
criteriaBuilder.and(
criteriaBuilder.greaterThanOrEqualTo(root.<Date>get(EmployeeTransaction_.requestedStartDate), join.get(Department_.id).<Date>get(DepartmentCompositeId_.departmentCreationDate)),
criteriaBuilder.lessThanOrEqualTo(root.<Date>get(EmployeeTransaction_.requestedStartDate), join.<Date>get(Department_.departmentCloseDate))
),
criteriaBuilder.isNull(root.get(EmployeeTransaction_.requestedStartDate)),
criteriaBuilder.isNull(join.get(Department_.id).get(DepartmentCompositeId_.departmentCreationDate))
));
criteriaQuery.select(root).where(predicates.toArray(new Predicate[]{}));
TypedQuery<EmployeeTransaction> query = entityManager.createQuery(criteriaQuery);
List<EmployeeTransaction> result = query.getResultList();
Этот вопрос, кажется, что я пытаюсь присоединиться строковый столбец, assigedDepartment, к одному полю составного идентификатора. Это совершенно законно в SQL, но не так просто в коде.
Один из вариантов заключается в том, чтобы преобразовать в число подзапросов, которые, кажется, полностью уничтожают точку левого внешнего соединения.
Может ли кто-нибудь указать, что я делаю неправильно?
Jason
Нет времени, чтобы написать ответ, но " выберите entity1 из entity1 left join entity1.field2 где ... ". Если вы хотите, чтобы левое соединение было с нетерпением, вам нужно иметь «левую вставку». –
Атрибут JoinType имеет только три возможных значения: INNER, LEFT и RIGHT. Кажется, что нет опции для левого соединения. Кроме того, в строке join() есть что-то не так. Несмотря на то, что join() возвращает SingularAttribute <>, я, похоже, не могу сгруппировать такие команды. – Jason
В запросе по критериям JPA вы ссылаетесь на таблицу 'DepartmentCompositeId', которая отсутствует в запросе SQL. Пожалуйста, заполните эту информацию, добавив соответствующие части определения каждого объекта. – perissf