Community
Participate
Working Groups
>Invalidating a cache object either invalidates the entire tree to the root (recurse=true) or invalidates a single entity (recurse=false) >The issue is we do not have the capability to invalidate a subtree starting at the invalidation class. in the following code when the recurse flag is false - we IdentityMapAccessor.java:820 public void invalidateClass(Class myClass, boolean recurse) { if (recurse || ((obj != null) && myClass.isInstance(obj)){ key.setInvalidationState(CacheKey.CACHE_KEY_INVALID); >Discussed this with James and we should align the code with what is done in IdentityMapManager.invalidateObject():581 if ((object.getClass() == theClass) || (theClass.isInstance(object))) { key.setInvalidationState(CacheKey.CACHE_KEY_INVALID); >by using isInstance() instead of equals() The following model illustrates this issue when we attempt to invalidate at different levels in the inheritance tree Class1 (non-persistable java class) +---Entity2 (abstract entity) +--- MappedSuperclass3 (MappedSuperclass) +-----Entity4a (concrete entity) +--- Class5 (non-persistable java class) +-----Entity4b (concrete entity) >currently if we evict() any of Class1 down to Class5 we evict the entire inheritance tree from Entity2 in all cases - This is because getIdentityMap(Class5 or any other) will return the identityMap for the root entity (Entity2) in all cases - by design Where the existing code becomes an issue is if we wish to invalidate only a subtree of the root descriptor by using recurse=false
>Existing code is IdentityMapAccessor.java:820 public void invalidateClass(Class myClass, boolean recurse) { if(recurse || ((obj != null) && obj.getClass().equals(myClass)){ key.setInvalidationState(CacheKey.CACHE_KEY_INVALID);
Created attachment 168037 [details] IdentityMapAccessor.invalidateClass() refactor to invalidate subtree
Created attachment 168038 [details] IdentityMapAccessor.invalidateClass() refactor to invalidate subtree
>The following model is used to to illustrate use case behavior when invalidating non-entity classes (extended functionality beyond the JPA specification) in an inheritance hierarchy. Class1 (non-persistable java class) +---Entity2 (abstract entity) +--- MappedSuperclass3 (MappedSuperclass) +-----Entity4a (concrete entity) +--- Class5 (non-persistable java class) +-----Entity4b (concrete entity) Entity4a and Entity4b are in the cache to start. >Here is the current behavior (all evict operations evict the entire tree) - This is because getIdentityMap(Class5 or any other) will return the identityMap for the root entity (Entity2) in all cases - by design evict(Class1) --> evicts E4a and E4b evict(Entity2) --> evicts E4a and E4b evict(MappedSuperclass3) --> evicts E4a and E4b evict(Entity4a) --> evicts E4a and E4b evict(Class5) --> evicts E4a and E4b evict(Entity4b) --> evicts E4a and E4b >I propose that we introduce more granular eviction behavior by not always evicting the root - but by evicting the subtree evict(Class1) --> evicts E4a and E4b evict(Entity2) --> evicts E4a and E4b evict(MappedSuperclass3) --> evicts E4a and E4b evict(Entity4a) --> evicts E4a only evict(Class5) --> evicts E4a only evict(Entity4b) --> evicts E4b only >Part of the change to enable this behavior is fixing the invalidateClass() function for cases where recurse=false See bug# 312503 - we may add a 2nd flag [recurseSubTree) to make the invalidateClass(Class) function (tri/quad state) recurse recurseSubtree behavior ------------------------------- false false :invalidate only class parameter - existing equals functionality false true :invalidate subtree from Class parameter - new isAssignableFrom functionality true false(x) :invalidate entire tree from root true true(x) :invalidate entire tree from root
Created attachment 170542 [details] IdentityMapAccessor.invalidateClass() refactor to invalidate subtree >The test suite used by the Cache API in bug# 248780 has sufficient inheritance levels for testing this change >The existing Project model suite passes with/without this change - as it is 1 level deep
>A documentation release note is required - previously when the (non-default) recurse flag of false was used - only the single class inside the tree was invalidated - now the entire subtree is invalidated - using the default behaviour of recurse=true has unaffected functionality - and removes the entire tree up to the root
>see SVN rev# 7447
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink