Reputation: 753
I have very complicated SQL written as native SQL. It's not possible to rewrite to JPL. It's a rewrite of some complicated logic implemented in Java code, but the filtering and paging is totaly unintuitive.
So I have a SQL with several temporary data sets created in with
. Primary data set is a list of promo actions matching basic conditions, then these records are extended with user info, then split to two sets (based on some user properties), then merged to final data set. All data sets hold info about promos including a priority. And I want to order by any column (e.g. by priority, date, ...).
So I have something like this (shortened for readability)
with xpromos as (
-- prepare promos matching global conditions
select distinct p.id, p.client_id, p.public_id as publicId,
p.points, p.display_from as displayFrom, p.display_to as displayTo,
p.valid_from as validFrom, p.valid_to,
p.type, p.country_id as countryId,
p.priority
from loyalty_promotion p
where p.country_id = :countryId
and p.valid_to > :time
), user as (
select id, points_balance
from lms_user lu
where id = :userId
), user_activated_promos as (
-- list of above promos which are activated for the user, extended with frontend state
select p.*, 'ACTIVE' as stateFE, null as remaining, p.valid_to as validTo
from xpromos p
where <conditions to get promos already activated by the user>
), user_available_promos as (
select p.*, 'AVAILABLE' as stateFE, p.points - lu.correct_balance as remaining, p.valid_to as validTo
from xpromos p
cross join user lu
where status = 'ACTIVE'
and p.id not in (select id from user_activated_promos)
), user_promos as (
-- final list of promos for later processing
select * from user_activated_promos
union
select * from user_available_promos
), promos as (
-- general promos for all
select distinct p.*
from user_promos p
where p.device_segment_id is null
union all
-- promos for segments
select distinct p.*
from user_promos p
join device_segment ds on p.device_segment_id = ds.id
join looser lu on ds.user_id = lu.id
)
select * from promos p
When I use this SQL in native query with Pageable(0,10,Sort.by("priority"))
I get an error in "order by" clause generated by JPA (or whatever) which is with(...) select * from promos p order by displayFrom.priority asc limit ?
So the displayFrom.priority
is obviously the wrong code. I don't understand it and I cannot figure out how to fix it.
@Query(value = "...above sql...", nativeQuery = true)
Page<LoyaltyPromotionFE> findActivePromotionsForFE(@Param("time") Instant time, @Param("countryId") String countryId, @Param("userId") String userId,
Pageable pageable);
I cannot figure out how to fix it. I read several threads on SO and Medium and tried to use SpEL, something like
order by :#{#pageable.getSort().iterator().next().getProperty()} :#{#pageable.getSort().iterator().next().getDirection()}
offset :#{#pageable.offset} rows
fetch next :#{#pageable.pageSize} rows only
but I just got other errors. SpEL expression are replaced with SQL placeholders ?
and it's not possible to use these in order by
.
Upvotes: 1
Views: 33