You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by David Minor <da...@gmail.com> on 2009/08/06 20:46:48 UTC

Problem with data cache, inverse relation, maybe parallel eager results

I have an entity A with a to-many relation to entity B. If entity A is
retrieved from the database, and entity B is found in the cache, the inverse
field from entity B to entity A is null.

StoreCollectionFieldStrategy.processEagerParallelResult() is setting a
"mapped by" field in the result object to entity A's object ID, however the
DataCacheStoreManager seems to not be aware of this and is trying to load
the inverse field in entity B, whereas the JDBCStoreManager has
setMappedBy().

DataCacheStoreManager appears to be attempting to load entity A all over
again, and subsequently entity B again, but there's so much delegation and
caching it's hard to tell.

This problem goes away if I revert the changes from
http://issues.apache.org/jira/browse/OPENJPA-744

If I change EagerFetchMode to "join" it seems to become rarer, but still
occurs.

I'm using 1.2.1.

Any ideas?

-- 
_____________
David Minor

Re: Problem with data cache, inverse relation, maybe parallel eager results

Posted by David Minor <da...@gmail.com>.
OK, I think I've figured out the general idea of what's going on:

1. Multiple Entity A's are requested (say A1, A2). The JDBCStoreManager
starts processing in parallel eager mode.
2. During the processing of A1, all Entity B's are processed in parallel
eager mode.
3. An Entity B belonging to A2 is found in the cache (say B2).
4. The cache has no knowledge of eager results, inverse relations, etc., and
loads *all* fields of B2.
5. B2 loads A2.
6. A2 loads all of its Entity B's. At this point the Entity B's
StateManager.isLoading() returns true and breaks the recursion.
7. SetInverseRelation() doesn't get applied to at least one of A2's entity
B, not sure why -- maybe because the Entity B was loaded in step 2?
8. After processing A1 has finished, BrokerImpl finds A2's StateManager in
its cache, so setInverseRelation() doesn't get called here either.

I found that if I changed the class structure a bit so that
DataCacheStoreManager is aware of the mapped by field in the current result,
and calls an implementation of setMappedBy() rather than loading that
particular field, then the problem went away.


On Thu, Aug 6, 2009 at 11:46 AM, David Minor <da...@gmail.com> wrote:

> I have an entity A with a to-many relation to entity B. If entity A is
> retrieved from the database, and entity B is found in the cache, the inverse
> field from entity B to entity A is null.
>
> StoreCollectionFieldStrategy.processEagerParallelResult() is setting a
> "mapped by" field in the result object to entity A's object ID, however the
> DataCacheStoreManager seems to not be aware of this and is trying to load
> the inverse field in entity B, whereas the JDBCStoreManager has
> setMappedBy().
>
> DataCacheStoreManager appears to be attempting to load entity A all over
> again, and subsequently entity B again, but there's so much delegation and
> caching it's hard to tell.
>
> This problem goes away if I revert the changes from
> http://issues.apache.org/jira/browse/OPENJPA-744
>
> If I change EagerFetchMode to "join" it seems to become rarer, but still
> occurs.
>
> I'm using 1.2.1.
>
> Any ideas?
>
> --
> _____________
> David Minor
>



-- 
_____________
David Minor