I have to query for about 20 to 30 results where some of the tables have m:n relations which I want to fetch their ids as well. So Hibernate ends up with the following SQL statement:
select
p1_0.person_id,
pp1_0.parent_person_id
from
person p1_0
left join
dependent_person pp1_0
on p1_0.person_id=pp1_0.child_person_id
where
p1_0.person_id in (1, 2, 3, 4)
The result sets for example look as follows:
person_id | parent_person_id |
---|---|
1 | null |
2 | null |
3 | 2 |
4 | 1 |
4 | 2 |
I want to project these rows to a DTO
respectively to a Map<Long, Set<Long>>
and don’t want to stress any overheads to Hibernate’s persistence context since there is no further need for the entities. So my question is now:
In concern of performance, which of the 2 following approaches is the better one:
- Get a result stream from the JPA TypedQuery#getResultStream method and collect the data to a Map using the Java Stream Collector API
- unwrwap to
org.hibernate.query.Query.class
and set a custom Hibernate’sResultListTransformer
to return the desired Map
I know that the setup of a Java Stream is costly and for only a few items a more or less slow process since the build up and tear down take their time. But unwrapping and hooking in a ResultListTransformer feels to cry for overhead as well.
Is there any knowledge about which way to go in terms of performance?
Many thanks for any clarification
Stay clear of
jakarta.persistence.Query#getResultStream
– it is broken by designericlippert.com/2012/12/17/performance-rant
@AndreyB.Panfilov thanks for this information. Can you be a little more specific or maybe have link at hand?
the only reason to use
Query#getResultStream
is the existence of some corner cases when you need to process the worth of data which does not fit into heap – that is definitely not your case. Moreover, pls read javadoc fororg.hibernate.query.Query#stream
: “You should call Stream.close() after processing the stream so that the underlying resources are deallocated right away” – as soon as you start usingQuery#getResultStream
you turn your fancy code intotry-with-resources
mess.@AndreyB.Panfilov Many thanks for this accurate information, that really helps – like always when I stumble across some answers of you 😉