Mam następujące zapytanie natywnego SQL, który próbuję przekonwertować do kryteriów WZP:Konwersja SQL LEFT OUTER JOIN Query do Kryteriów WZP
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)
(Zauważ, że (+) jest mniej więcej odpowiednikiem zewnętrzna lewa dołącz do tej sprawy. Tak, wiem, że oznacza ona tabelę OPCJONALNĄ itp.).
Oto moja próba na kod:
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();
Kwestia ta wydaje się być to, że staram się dołączyć do kolumny ciąg, assigedDepartment, do jednego pola złożonego ID. Jest to całkowicie legalne w SQL, ale nie tak łatwe w kodzie.
Jedną z opcji jest konwersja na wiele podkwerend, co wydaje się całkowicie zabijać punkt lewego zewnętrznego sprzężenia.
Czy ktoś może wskazać, co robię źle?
Jason
Nie ma czasu, aby napisać odpowiedź, ale " wybierz entity1 z entity1 left join entity1.field2 where ... ". Jeśli chcesz, aby lewe połączenie było chętnie pobierane, musisz "pobrać lewostronne". –
Atrybut JoinType ma tylko trzy możliwe wartości: INNER, LEFT i RIGHT. Wydaje się, że nie ma opcji pobierania z lewej strony. Występuje również problem z linią join(). Mimo, że join() zwraca SingularAttribute <>, nie mogę wydawać się łańcuchami takich poleceń. – Jason
W kwerendzie zapytania JPA odwołujesz się do tabeli 'DepartamentCompositeId', której nie ma w zapytaniu SQL. Uzupełnij informacje, dodając odpowiednie części definicji każdego podmiotu. – perissf