I’m trying to use Hibernate to retrieve approximately 100 million rows from a table. I have a persisted entity Item that contains a collection of Fees inside (another persisted entity). Given that I will iterate over the result and access the fees for every object, I want to eagerly fetch fees to avoid the n+1 problem.
I should also mention that I want to join it to another table called Provider (one-to-one mapping but no foreign key). I tried:
String query = "select new " + Order.class.getName()
+ "(i, p) from Item i left join fetch i.fees f, Provider p where "
+ "p.factoryId=i.factoryId and p.factoryRef=i.factoryRef";
return session.createQuery(query).scroll();
My Order class contains a Provider field and an Item field. I get this error:
Caused by: org.hibernate.QueryException: query specified join
fetching, but the owner of the fetched association was not present in
the select list
I would like to end up with a scrollable list of Order which contain Item (with the fees eagerly fetched) and Provider.
This code from
SelectClausecauses you the trouble :As you can see, when the fetch keyword is mentioned, hibernate checks to see if you asked for the fetch decorated field parent.
fromElementsForLoad.contains( origin )They probably did it to defend you from making a redundant join that will cost you a lot in performance. It’s a good thing cause there’s no reason for fetching the association if you never use it.
I believe that in your case – wrapping the
Item.classin the newOrder.classhides the fact that you do use the fetch decorated field parent in the query.I have no debugging abilities at the moment so I can’t validate this. try and debug this exact row from SelectClause.class and see what elements the
fromElementsForLoadcollection holds.If you want to avoid the n+1 problem I would recommend initializing the Order.class after the query. You can select only the Item and Provider.
If you can’t validate this, I’ll get to a proper computer next week and expand my answer.