Используя Spring Data JPA с QueryDsl, разбиение на страницы разбивает сортировку
Учитывая следующий запрос, мои результаты сортируются по номеру заказа в порядке убывания. При попытке вернуть постраничные результаты сортировка прерывается. Я пробовал это без выражения.orderBy() и добавления экземпляра QSort в мой QPageRequest. Я пытался вызвать метод applySorting() напрямую и передать QSort, но для всех интенсивных целей вызов разбиения на страницы нарушает любой вид сортировки, который я пытаюсь.
Я использую QueryDsl 3.3.4 и Spring Data JPA 1.6.4. как импортировано Spring IO BOM 1.0.3.
public List<Object[]> findAll(PersonProfile personProfile) {
QOrderStop shipper = new QOrderStop("shipper");
QOrderStop consignee = new QOrderStop("consignee");
JPQLQuery query = this.from(order)
.leftJoin(order.orderStops, shipper).on(shipper.originalStopSequence.eq(BigDecimal.valueOf(1)))
.leftJoin(order.orderStops, consignee).on(consignee.originalStopSequence.intValue().eq(order.orderStops.size()))
.where(order.company.eq(company).and(OrderExpressions.customerCodePredicate(order, personProfile)))
.orderBy(order.number.desc());
//this.getQuerydsl().applyPagination(new QPageRequest(0, 10), query);
return query
.list(
order.number, order.status, order.shipperReferenceNumber, order.consigneeReferenceNumber,
order.shipperCustomer.billingCity, order.shipperCustomer.state,
shipper.latestScheduleDate, shipper.latestScheduleTime,
order.consigneeCustomer.billingCity, order.consigneeCustomer.state,
consignee.latestScheduleDate, consignee.latestScheduleTime
).stream()
.map(Tuple::toArray)
.collect(toList());
}
РЕДАКТИРОВАТЬ - Использование.limit(20) для нумерации страниц вместо.applyPagination ()
query.toString () перед query.limit(20)
select order1
from Order order1
left join order1.orderStops as shipper on shipper.originalStopSequence = ?1
left join order1.orderStops as consignee on cast(consignee.originalStopSequence integer) = size(order1.orderStops)
where order1.company = ?2 and (order1.customer = ?3 or order1.billTo in ?4 or order1.shipper in ?5 or order1.consignee in ?5)
order by order1.number desc
query.toString () после query.limit(20) - без изменений
select order1
from Order order1
left join order1.orderStops as shipper on shipper.originalStopSequence = ?1
left join order1.orderStops as consignee on cast(consignee.originalStopSequence integer) = size(order1.orderStops)
where order1.company = ?2 and (order1.customer = ?3 or order1.billTo in ?4 or order1.shipper in ?5 or order1.consignee in ?5)
order by order1.number desc
Окончательный вывод запроса EclipseLink
SELECT * FROM (SELECT * FROM (SELECT EL_TEMP.*, ROWNUMBER() OVER() AS EL_ROWNM FROM (SELECT t0.OHOR# AS a1, t0.OHORST AS a2, t0.OHSRF# AS a3, t0.OHCRF# AS a4, t1.CUBCTY AS a5, t1.CUBST AS a6, t2.BSLSDT AS a7, t2.BSLSTM AS a8, t3.CUBCTY AS a9, t3.CUBST AS a10, t4.BSLSDT AS a11, t4.BSLSTM AS a12 FROM LIB.DPORDHP t0 LEFT OUTER JOIN LIB.DPORDSP t2 ON (((t2.BSOR# = t0.OHOR#) AND ((t2.BSOL# = t0.OHORS#) AND (t2.BSCM = t0.OHCM))) AND (t2.BSRSQS = ?)) LEFT OUTER JOIN LIB.DPORDSP t4 ON (((t4.BSOR# = t0.OHOR#) AND ((t4.BSOL# = t0.OHORS#) AND (t4.BSCM = t0.OHCM))) AND (CAST(t4.BSRSQS AS integer) = (SELECT COUNT(t5.BSOR#) FROM LIB.DPORDSP t5 WHERE ((t5.BSOR# = t0.OHOR#) AND ((t5.BSOL# = t0.OHORS#) AND (t5.BSCM = t0.OHCM)))))), LIB.SWCUSTP t3, LIB.SWCUSTP t1 WHERE (((t0.OHCM = ?) AND ((((t0.OHCUST = ?) OR (t0.OHBID IN (?,?))) OR (t0.OHSID IN (?,?,?,?,?,?,?,?,?,?))) OR (t0.OHCID IN (?,?,?,?,?,?,?,?,?,?)))) AND (((t1.CUCID = t0.OHSID) AND (t1.CUCM = t0.OHCM)) AND ((t3.CUCID = t0.OHCID) AND (t3.CUCM = t0.OHCM)))) ORDER BY t0.OHOR# DESC) AS EL_TEMP) AS EL_TEMP2 WHERE EL_ROWNM <= ?) AS EL_TEMP3 WHERE EL_ROWNM > ?
1 ответ
Я не знаю, как applyPagination нарушает порядок, но было бы более интуитивно понятно использовать здесь query.limit и query.offset, так как вы находитесь внутри метода репозитория.
...
.orderBy(order.number.desc()).
.limit(pageSize)
.offset((page-1) * pageSize);