JPA TypedQuery#getResultStream vs Hibernate Query#setResultListTransformer in terms of Performance?

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:

  1. Get a result stream from the JPA TypedQuery#getResultStream method and collect the data to a Map using the Java Stream Collector API
  2. unwrwap to org.hibernate.query.Query.class and set a custom Hibernate’s ResultListTransformer 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

  • 1

    Stay clear of jakarta.persistence.Query#getResultStream – it is broken by design

    – 

  • @AndreyB.Panfilov thanks for this information. Can you be a little more specific or maybe have link at hand?

    – 

  • 1

    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 for org.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 using Query#getResultStream you turn your fancy code into try-with-resources mess.

    – 

  • @AndreyB.Panfilov Many thanks for this accurate information, that really helps – like always when I stumble across some answers of you 😉

    – 

Leave a Comment