You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Daryl Stultz <da...@6degrees.com> on 2009/10/08 17:12:28 UTC

left join fetch weirdness

Hello,
Suppose I have entity A with field "bCol" which is a collection of "B". I
have 2 records of A, a1 having 2 B instances in bCol and a2 having 3 B
instances in bCol. I run this query to load the list of all A's and pre
fetch bCol:

// get em 1
select a from A as a
left join fetch a.bCol
// close em 1

I get 2 instances of A as expected, a1 and a2. Then I edit a2, first by
getting a fresh, deep instance:

//get em2
select a from A as a
left join fetch a.bCol
where a.id = 2
// close em 2
... make edit to a2
// get em3
em3.merge(a2);

Then I reload the original list using the first query:
select a from A as a
left join fetch a.bCol
// close em 3

This time I get 4 rows with 3 copies (same hashCode) of a2 (apparently one
for each B child in bCol). It's as if the left join fetch turns into a left
join. Adding "distinct" to the query doesn't help. Interestingly I get only
1 instance of a1 even though it's got 2 in bCol. Note that the reload
happens on em3 - the same that the merge was done. If I call em3.clear()
before reloading, it works as expected, also if I close em3 and get em4
before reloading the list.

Am I not understanding something? Is there some aspect of L1 cache I'm not
handling properly?
Thanks.

OpenJPA 1.2.1.

-- 
Daryl Stultz
_____________________________________
6 Degrees Software and Consulting, Inc.
http://www.6degrees.com
mailto:daryl@6degrees.com

Re: left join fetch weirdness

Posted by Daryl Stultz <da...@6degrees.com>.
On Thu, Oct 8, 2009 at 1:21 PM, Miłosz Tylenda <mt...@o2.pl> wrote:

> Hi Daryl,
>
> I can see the oddity but an "inversed" one. I would say that
>
> > // get em 1
> > select a from A as a
> > left join fetch a.bCol
> > // close em 1
>
> should return 5 instances of A (2 x a1 and 3 x a2). Prefetching will not
> make instances "distinct".
>
> Thanks for the feedback. It seems clear there's both a problem with my
understanding as well as the implementation. From the manual:

The following query returns a set of magazines. As a side effect, the
associated articles for those magazines are also retrieved, even though they
are not part of the explicit query result. The persistent fields or
properties of the articles that are eagerly fetched are fully initialized.
The initialization of the relationship properties of the articles that are
retrieved is determined by the metadata for the Articleentity class.

SELECT mag FROM Magazine mag LEFT JOIN FETCH mag.articles WHERE mag.id = 1

A fetch join has the same join semantics as the corresponding inner or outer
join, except that the related objects specified on the right-hand side of
the join operation are not returned in the query result or otherwise
referenced in the query. Hence, for example, if magazine id 1 has five
articles, the above query returns five references to the magazine 1 entity.

The green part I understood to mean only one parent entity would be returned
(the way my query works from a fresh start). The purple part seems to
contradict the preceding green part and agrees with what you are suggesting.

-- 
Daryl Stultz
_____________________________________
6 Degrees Software and Consulting, Inc.
http://www.6degrees.com
mailto:daryl@6degrees.com

Re: left join fetch weirdness

Posted by Miłosz Tylenda <mt...@o2.pl>.
Hi Daryl,

I can see the oddity but an "inversed" one. I would say that

> // get em 1
> select a from A as a
> left join fetch a.bCol
> // close em 1

should return 5 instances of A (2 x a1 and 3 x a2). Prefetching will not make instances "distinct".

This looks like a bug described in OPENJPA-894 [1].

[1] http://issues.apache.org/jira/browse/OPENJPA-894

Cheers,
Milosz


> Hello,
> Suppose I have entity A with field "bCol" which is a collection of "B". I
> have 2 records of A, a1 having 2 B instances in bCol and a2 having 3 B
> instances in bCol. I run this query to load the list of all A's and pre
> fetch bCol:
> 
> // get em 1
> select a from A as a
> left join fetch a.bCol
> // close em 1
> 
> I get 2 instances of A as expected, a1 and a2. Then I edit a2, first by
> getting a fresh, deep instance:
> 
> //get em2
> select a from A as a
> left join fetch a.bCol
> where a.id = 2
> // close em 2
> ... make edit to a2
> // get em3
> em3.merge(a2);
> 
> Then I reload the original list using the first query:
> select a from A as a
> left join fetch a.bCol
> // close em 3
> 
> This time I get 4 rows with 3 copies (same hashCode) of a2 (apparently one
> for each B child in bCol). It's as if the left join fetch turns into a left
> join. Adding "distinct" to the query doesn't help. Interestingly I get only
> 1 instance of a1 even though it's got 2 in bCol. Note that the reload
> happens on em3 - the same that the merge was done. If I call em3.clear()
> before reloading, it works as expected, also if I close em3 and get em4
> before reloading the list.
> 
> Am I not understanding something? Is there some aspect of L1 cache I'm not
> handling properly?
> Thanks.
> 
> OpenJPA 1.2.1.
> 
> -- 
> Daryl Stultz
> _____________________________________
> 6 Degrees Software and Consulting, Inc.
> http://www.6degrees.com
> mailto:daryl@6degrees.com
>