JPA данных Spring добавляет неверную запятую перед параметрами сортировки - PullRequest
0 голосов
/ 25 марта 2019

Я использую Spring-Boot 2.1.3.RELEASE, включая spring-boot-starter-data-jpa. (Я не использую data-rest.) Моя база данных - Postgres.

У меня есть собственный запрос, к которому я применяю параметры подкачки и копирую результаты в проекцию. Простая версия запроса работает как шарм: магия Spring автоматически добавляет параметры сортировки / подкачки при вызове. Но когда я пытаюсь сделать запрос немного сложнее, добавив левое внешнее соединение, Spring начинает добавлять запятую перед параметрами сортировки / подкачки, что делает запрос недействительным.

Это простой запрос, который работает:

@Query( nativeQuery = true,
        value = "SELECT order.date, order.volume, customer.name " +
                 FROM example.order " +
                 INNER JOIN example.customer ON order.customer_id = customer.id " +
                 WHERE customer.state = :state ",
        countQuery = "SELECT count(order.id) " +
                      FROM example.order " +
                      INNER JOIN example.customer ON order.customer_id = customer.id " +
                      WHERE customer.state = :state "
)
<T> Page<T> findOrdersByCustomerState(String state, Pageable pageable, Class<T> projection);

Hibernates сообщает, что генерирует SQL, и это хорошо, и параметры подкачки применены, как и ожидалось:

SELECT order.date, order.volume, customer.name FROM example.order INNER JOIN example.customer ON order.customer_id = customer.id 
WHERE customer.state = ? order by order.date desc limit ?

(Где date был передан в Pageable.)

Теперь я пытаюсь расширить этот запрос, добавив левое внешнее соединение, чтобы получить дополнительные данные:

SELECT order.date, order.volume, customer.name, historic_orders.order_date 
FROM example.order 
INNER JOIN example.customer ON order.customer_id = customer.id 
LEFT JOIN example.historic_orders ON historic_orders.id IN 
  (SELECT historic_orders.id FROM example.historic_orders WHERE 
   historic_orders.customer_id = customer.id ORDER BY historic_orders.order_date 
 LIMIT 1)
WHERE customer.state = :state

В основном я присоединяюсь к таблице historic_orders, в которой может не быть записей об этом клиенте, поэтому я могу получить дату последнего заказа.

В любом случае, Hibernate теперь генерируется так:

SELECT order.date, order.volume, customer.name, historic_orders.order_date 
FROM example.order 
INNER JOIN example.customer ON order.customer_id = customer.id 
LEFT JOIN example.historic_orders ON historic_orders.id IN 
(SELECT historic_orders.id FROM example.historic_orders WHERE historic_orders.customer_id = customer.id ORDER BY historic_orders.order_date 
 LIMIT 1)
WHERE customer.state = ?, INNER.date desc limit ?

Это, конечно, недопустимый SQL. Перед параметром sort / paging стоит случайная запятая, и по какой-то причине было решено, что она должна быть отсортирована по таблице INNER ... которая не существует.

Единственное исключение из самой базы данных:

PSQLException: ОШИБКА: синтаксическая ошибка в или около ","

Как применить разбиение на страницы / сортировку к запросу с левым соединением? Добавление параметра Pageable достаточно для простых запросов с внутренними объединениями, но при левом соединении генерируется недопустимый SQL. Нужно ли применять ручную подкачку? Я делаю это неправильно, или это ошибка, о которой я должен сообщать пользователям данных Spring?

В качестве примечания я попытался обходной путь до версии 2.0.4 с использованием -- #pageable. При этом все еще генерировался тот же недействительный SQL, но он был закомментирован, поэтому база данных не жаловалась… мои данные оказались не такими, как я ожидал.

Далее, если я уберу параметры сортировки, предел будет применен без посторонней запятой. То есть, если я передаю ему Pageable, который имеет параметры подкачки, но не сортирует параметры, он правильно возвращает запрос с примененным пределом / смещением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...