I added OpenJPA test cases to 
https://issues.apache.org/jira/browse/OPENJPA-2296 that show the bug 
(TestRecursiveEagerSQL.java).

The N+1 select problem also occurs for ManyToOne when we only have two 
entities. E.g. A OneToMany B and when the ManyToOne relation from B to A is 
eager and we select B: then for each B it's A is loaded using a separate query, 
see TestManyOneEagerSQL.java. For A OneToOne B the problem does not occur, see 
TestOneOneEagerSQL.java. 

I also found a partial fix: it can be fixed for the parallel eager select 
strategy by having RelationFieldStrategy.selectEagerJoin not limit recursive 
eager fetching to JOIN. I ran all tests in persistence-jdbc and it does result 
in the existing TestManyEagerSQL failing with duplicates in the list, perhaps 
this can be fixed using DISTINCT? (TestJPQLSubquery also fails but only because 
it is too sensitive to the generated SQL and is easily adjusted). 

The join eager select strategy is not used at 
JDBCStoreManager.createEagerSelects because 
 - boolean hasJoin = fetch.hasJoin(fms[i].getFullName(false)); is false 
 - inEagerJoin = true (select query already has an eager to-one join) 

I do not know if this can be fixed as well. 

Finally a workaround can be done by using cached entities in the entity manager 
context. Simply select all entities that are otherwise loaded by their id as in 
the "load field" trace. 
For the Company - Employee - Project example this would mean performing the 
query "SELECT e FROM Employee e" before the actual query.

So for Sirisha's problem selecting all B objects that would be returned inside 
the object graph return by the query for A could solve the problem.

Reply via email to