On Aug 27, 2009, at 2:45 PM, Bob Morley wrote:


Today I spent some time figuring out why our entity list cache was not
working as expected. We had a PartyContent entity that was fetched in a
entity-and with use-cache="true".  However, when the PartyContent was
updated the cache was not properly flushed in the EntityList cache. Here is
what I found:

1) Cache.remove(GenericEntity entity) is being called with the updated
GenericEntity. This is used to call entityListCache.storeHook(entity, null)
and the signature expects to have oldvalue, newvalue.  Ultimately it
iterates through the conditions and attempts to programatically apply them to the "old value". If there is match that condition is removed from the cache. The trouble of course, is that it is using the new value which may
cause the condition to no longer match (as in our case).

2) During the comparison logic for the condition (above) the system
ultimately gets down to EntityJoinOperator.entityMatches(GenericEntity, lhs, rhs). This object has a "shortCircuitValue" (basically when should I stop checking for this condition). For our AND the short circuit value would be "false" as in if I hit false on the left-hand-side there is no point in checking the right-hand-side, lets leave now with FALSE. The trouble was
the code looked like:

if (lhs.entityMatches(entity)) return shortCircuitValue;

instead of

if (lhs.entityMatches(entity) == shortCircuitValue) return
shortCircuitValue;

This pattern is in a few places, it was just wrong in this method and
mapMatches method (right below).

SO, I have a clear fix for #2 but my solution for #1 isn't great (I go fetch the entity from the database so I can get the "old value"). I would like to talk with someone with lots of caching experience here to make sure I am not off base. Also, wonder if there is a way to get the original version of the GenericEntity without doing a re-fetch. I was considering an solution where the fields would be changed to a MapStack where the updated fields would be
on the top of the stack (always a stack of 2).

Thoughts?

The GenericEntity object keeps a Map with original values if it was loaded from the database and then changed, so you should be able to use that (it does seem weird that it isn't used already!).

-David


Reply via email to