Hello community,
I'm trying to execute an HQL query for a report using
Hibernate 3.6.1, where I'm selecting from one of my entities "Customer" and joining an "issues" collections for some computed statistics over said issues into a row bean constructor. In order to have every row relate to exactly one customer, I'm properly grouping on the entity. The Customer entity is batch-loading enabled (batch-size="100"), as is the "issues" collection. My case is actually very basic and my approach is straight forward, so I'm simplifying away some company-secrets here:
Code:
select new company.product.report.ReportRowBean(customer, count(issues), sum(issues.effort))
from Customer customer
left join customer.issues issues
group by customer
where ...
Code:
select customer0_.ID as col_1_0_, count(issues1_.ID) as col_2_0_, sum(issues1_.EFFORT) as col_3_0_
from CUSTOMER customer0_
left join ISSUE issues1_ on issues1_.CUSTOMER_ID = customer0_.ID
group by customer0_.ID
where ...
Hibernate properly avoids to select the whole Customer entity at once because of the grouping, i.e. it only selects and groups on the customer's ID. That's fine and exactly what I want. However, when extracting rows from the result set, Hibernate immediately fires single loads for every single customer, instead of batch loading them after the result set extraction has finished, i.e. Hibernate is not creating lazy proxies as arguments to the ReportRowBean constructor but rather loads and initializes concrete customer instances for each result row before even looking at the next row. This poses an N+1 problem, that I can't seem to circumvent as it appears to be internal to Hibernate's query loading strategy. I think it has to do with Hibernate assuring a customer exists by eagerly selecting it (see "load() vs. get()" topic). I have no idea, what I could do (reconfigure, rewrite query, etc.) to prevent Hibernate from loading single customers during the result-set extraction process of the global query. Any suggestions what to do and/or where to look are very welcome. It would also help to know, if it's even possible to have Hibernate select proxies into a row bean constructor, since I have the feeling it isn't.
My customers are lazy, batchable and they don't have any one-to-one associations or fancy joined-subclasses that could trigger eagerness.
EDIT:
Replacing the aggregated computations over the issues collection with neat sub-selects to remove the grouping requirement is not an option, since I'm also using these aggregates to order the result.