openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeff Oh <>
Subject Advice Requested: Instance Loading bug in 2.3.0
Date Fri, 02 May 2014 23:36:57 GMT
Hello All,

We've recently upgraded to 2.3.0 (from 1.2.2) and have encountered a nasty bug where when
loading a complicated cyclic object graph using a fetch group, some relationships are not
being populated under some circumstances.

Unfortunately, the graph really is quite complicated, and while I have a set of test data
where the problem can be reliably duplicated, I haven't been able to make an integration test
do the same yet.  A simplified version of the graph is that A is 1:M to B and A is 1:M to
C, B is M:1 to A (Bidirectional), and C is M:1 to A and C is also M:1 to B.  The net effect
is a graph where cycles can exist, although in practice they generally don't other than the
bidirectional relationship between A and B.

Our failing case is interesting.  When we load single instances of B (call them B1 and B2)
one at a time the load is always successful, with all of the A, B, and C relationships populated
- but only if loaded one at a time.  In other words, if we run entityManager.find(B1) or entityManager.find(B2),
then all is well.

An ascii art version of the graph traversals might look something like this:

B1 -> A1 -> C1    -> B3      -> A3     -> B3        -> A3
                                                     -> B3-1     -> A3
                                                     -> B3-2     -> A3
              -> C1-2 -> ...

B2 -> A2 -> C2    -> A3       -> B3       -> A3
                                         -> B3-1    -> A3
                                         -> B3-2    -> A3
              -> C2-2 -> ....

where B is M:1 to A, A is 1:M to C and A is 1:M to B.

Interestingly, while B1 and B2 are separate objects, they do share several common objects
in their graphs - call them A3 and B3 (as well as B3-1 and B3-2).  If we run a query that
loads both B1 and B2 in the same query - entityManager.find(B1 + B2), then one of the relationships
from one of the other B objects in the graph (call it B3) B3->A is null (not populated),
where B3->A should == A3.  To clarify, B1.A1.C1.B3.getA() should equal A3, and instead
is null, and B2.A2.C2.A3.B3.getA() should also equal A3, but instead is null.

Of course, the graph is being detached after load, so unfortunately lazy loading the B3->A
relationship is not possible.

When running through a debugger, it looks like what happens is that the A3 and B3-* instances
are each being created more than one time.  This seems to make sense because the graph has
cycles, relationships are loaded recursively, and instances are not added to the transactional
cache (ManagedCache) until after they are fully initialized with all fields loaded.   Therefore
new instances will not always be fully created when they are needed again.  As the call stack
goes forward, the newest A and B instances get fully initialized with all fields loaded. 
However, as the call stack unwinds, the oldest A and B instances are the ones that eventually
win, and one of the B instances that wins is not fully initialized and has a null field in
it's A relationship (e.g. B3.getA() is null, because B3's A was not ever set).

I'm currently tracing this through to try and determine exactly why the outer (eldest) B3
isn't getting loaded with its A3, but while I do so, I was wondering if anyone else has encountered
a similar problem or has any suggestions as to where I should focus my efforts.

My current thinking is that the multiple loading issue is OK and expected, and that the problem
is that the oldest B's aren't getting loaded with their A's.  But it is possible that the
problem is that each individual entity should only be initialized once, and that the problem
is that OpenJPA is instantiated multiple copies of each B and A and should only ever be instantiating
one per id.  Comments would be welcome.



Jeff Oh, Sr. Software Engineer
Phone: 604.408.8078 ext. 104

Elastic Path Software Inc.
Web <> | Blog <>
| Twitter <>
Careers<> | Community

Confidentiality Notice: This message is intended only for the use of the designated addressee(s),
and may contain information that is privileged, confidential and exempt from disclosure. Any
unauthorized viewing, disclosure, copying, distribution or use of information contained in
this e-mail is prohibited and may be unlawful. If you received this e-mail in error, please
reply to the sender immediately to inform us you are not the intended recipient and delete
the email from your computer system.

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message