The problem seems to be that in org.apache.openjpa.jdbc.sql.SelectImpl, as
it's building up the necessary select statements, it keeps a HashSet of the
fields that already have eager selects created for them, and doesn't create
another eager select if one already exists for that particular field.

So, when requesting a particular entity of class A { List<B> bs; List<A>
children; }, OpenJPA creates parallel eager selects for 'A.bs' and
'A.children', but then as it examines 'children', it doesn't create a
parallel eager select for their 'bs' since the field 'A.bs' already has an
eager select for it according to the HashSet.

Later as it's loading the data it uses individual statements to get the
missing data.

There's a comment in JDBCStoreManager prior to the call to
createEagerSelects():

// create all our eager selects so that those fields are reserved
// and cannot be reused during the actual eager select process,
// preventing infinite recursion

which makes sense, since you wouldn't necessarily want to select the
children's children's children, etc. But in this case, it seems to prevent
efficient selection of desired fields.

I believe this is also the cause of the problem reported in
https://issues.apache.org/jira/browse/OPENJPA-2299

In that case you have class A { List<B> list1; List<B> list2; }, and eager
selects are created for list1's collection fields but not list2 (since both
lists are of entity B).

________________________________________
From: Rick Curtis <curti...@gmail.com>
Sent: Thursday, July 10, 2014 5:58 AM
To: users
Subject: Re: Avoiding N+1 on collection in recursive relation

David -

It seems like this question has been asked numerous times on this mailing
list and no one has come up with a good answer. I too don't have an answer,
but if you come up with anything please post back to the list.

Thanks,
Rick


On Tue, Jul 8, 2014 at 6:56 PM, David Minor <davemi...@gmail.com> wrote:

> I have an entity (A) that has a recursive OneToMany relation with itself
> (children). A also has a OneToMany relation to entity B.
>
> Whenever A is fetched, the queries to fetch B for entity A and its
children
> are all separate queries.
>
> Is there any way to avoid this?
>
> --
> _____________
> David Minor
>



--
*Rick Curtis*

-- 
_____________
David Minor

Reply via email to