Reputation: 93
So I'm migrating some services from and old application that used native queries to retrieve data and I've found some issues and would like to discuss what would be the best way to solve them.
The main problem is that this service uses a native query that encloses several other queries that are connected via UNION
statement. Something like this:
WITH TMP_QUERY AS (
select p.id,p.name from PROCESS p inner join TABLE_B on ...
UNION
select p.id,p.name from PROCESS p inner join TABLE_C on ...
UNION
select p.id,p.name from PROCESS p inner join TABLE_A on ...)
select p.name from PROCESS p inner join TMP_QUERY tmp on p.id = tmp.id order
by 1
And because JPA
does not support the UNION
statement the only solution I've thought about is to execute these queries separately and then do the duplicate removal, ordering and pagination in java code.
Maybe adding the results to a set in order to remove the duplicates and then apply a Comparator
to order the returned entities. BUT the other issue is that I also require pagination because any of those queries could return from 10 to maybe 1000s of results which will lead to server timeout problems.
Has anyone dealt with something similar?
Upvotes: 4
Views: 9503
Reputation: 21
Union/Union All will work if you change it to a native query and use like below
//In Your Entity class
@NamedNativeQuery(name="EntityClassName.functionName",
query="your_native_query")
//In your Repository class
@Query(native=true)
List<Result> functionName();
Below method of defining Native query in JPA repository will not solve this problem
@Query(value="your_native_query", native=true)
will not
Upvotes: 0
Reputation: 26522
I think you could replace those UNION statements with subqueries and use JPQL / HQL to achieve the usage of persistence provider orm support:
select p.name as name
from Process p
where (p.id, p.name) in
(
select pp.id,pp.name from Process pp inner join pp.tableB b ...
)
or (p.id, p.name) in
(
select pp.id,pp.name from Process pp inner join pp.tableC c ...
)
or (p.id, p.name) in
(
select pp.id,pp.name from Process pp inner join pp.tableA a ...
)
order by name
Upvotes: 3