Community
Participate
Working Groups
JPA 2.0 has added a simplistic Cache interface to allow developers to interrogate the cache and invalidate entities that exist there.
Created attachment 119224 [details] svn diff The above attachment shows the changes that are made in EntityManagerFactoryImpl and EntityManagerFactory interface.
Created attachment 119225 [details] Implementation of Cache interface This is a class that implements the methods of Cache interface.
Created attachment 119226 [details] Cache Interface This is a Cache interface that defines the methods
Created attachment 119227 [details] CacheImpl Junit test This class tests the methods of CacheImpl.java.
Created attachment 119334 [details] patch file of svn diff This is a updated patch of the svn diff. Please do ignore the previous files.
Created attachment 119345 [details] bug-248780.patch
Created attachment 119399 [details] updated patch for bug-248780 patch updated with the changes suggested by Gordon.
Created attachment 119443 [details] updated patch for bug-248780
Created attachment 119532 [details] updated patch of Bug#248780 updated patch with the changes suggested by Andrei.
Checked in patch provided by Darani (Revision 2896)
Is there a possibility of a relation between JPA 2.0 Cache API and the JCACHE API(JSR 107)? How about making the JPA 2.0 API a subset of JCACHE API ? May be eventually it may result in fully implementing the JCACHE spec ?
I was reviewing some of the JPA 2.0 features and have a few issues we should address in the implementation of Cache. http://dev.eclipse.org/svnroot/rt/org.eclipse.persistence/trunk/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/CacheImpl.java 1. Unsure if we need to hold all of this state or just hold the EMF and access the necessary IdentityMapAccessor through this access. 2. We will need to support more then just ServerSession so we need to have impls such as this just rely on more general interfaces for the shared session such as Session or DatabaseSession interfaces. 3. The createPKVector does not handle the case where the descriptor does not have a CMPPolicy. This occurs when bootstrapping from native metadata. Also does not properly handle the case where the cls provided is not associated with a descriptor. 4. Should we support passing in MappedSuperclass or general types from the entity inheritance tree? I believe we should.
Changed target from 1.1 to 2.0
Supporting MappedSuperClass would be very strange as a MappedSuperClass is not really a cached type nor is it a mapped hierarchy member. In many cases supporting evicting a MappedSuperClass and interpreting that to mean evict all extenders would mean the whole cache gets evicted. I recommend throwing an IllegalArgumentException if a class type other than an entity is passed in to this code. Supporting evicting all subclasses of an Inheritance hierarchy also requires some tweaking as the current call would remove all members of the hierarchy and not just subclasses.
The comment on javax.persistence.Cache states: /** * Remove the data for entities of the specified class (and its subclasses) * from the cache. */ public void evict(Class cls); Trying this class as a mapped entity first is simple enough. If it is mapped it will follow the implied subclasses requirement. Even if it is the root of an inheritance tree no additional work is required. The only tough part is when a developer passes in a non-entity class that may be a mapped superclass or may simply be a class or interface shared by mapped entity classes. I believe we can solve this using something like: /** * Invalidate all cached entities of the provided class. Since classes in * inheritance hierarchies share a cache the only additional inheritance * support is for classes which don't correspond to entities. * * @see Cache#evict(Class) */ public void evict(Class cls) { getEntityManagerFactory().verifyOpen(); ClassDescriptor descriptor = getEntityManagerFactory().getSession().getClassDescriptor(cls); if (descriptor != null) { getEntityManagerFactory().getSession().getIdentityMapAccessor().invalidateClass(cls); return; } // Since no specific descriptor was found iterate over all descriptors // and initialize the cache of those types that can be assigned to the // provided class/interface Iterator descI = getEntityManagerFactory().getSession().getDescriptors().values().iterator(); while (descI.hasNext()) { ClassDescriptor desc = (ClassDescriptor) descI.next(); if (!desc.isChildDescriptor() && !desc.isAggregateDescriptor() && cls.isAssignableFrom(desc.getJavaClass())) { getEntityManagerFactory().getSession().getIdentityMapAccessor().invalidateClass(cls); } } } I am attaching my impl that I believe will work but needs to be reviewed and verified. Doug
Created attachment 131077 [details] Proposed Solution
Changing priority to P@ since JPA 2.0 features are required for the 2.0 release
This issue is complete as required for JPA 2.0 functionality. so it no longer blocks bug 24891 .
>starting investigation for updates to original SVN Rev# 2896 based on feedback by Doug C. http://fisheye2.atlassian.com/changelog/~author=mmeswani/eclipselink/?cs=2896 >Does not block parent JPA 2.0 bug# 248291
The implementation was modified on the following dates as follows that will affect the refactor diff... 20100201: Rev# 6463 - bug# 301063 : Refactor CacheImpl to implement the EclipseLink API interface JpaCache (which implements Cache from JPA 2.0 via the new functions - clear(), clear(Class), clearQueryCache(), clearQueryCache(queryName), timeToLive(Object), isValid(Object), isValid(Class, id), print(), print(Class), printLocks(), validate(), getObject(Class, id), getObject(Object), putObject(Object), removeObject(Class), removeObject(Class, id), containsObject(Object), evictObject(Object), getId(Object) http://fisheye2.atlassian.com/browse/eclipselink/trunk/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/CacheImpl.java?r=6463 20100126: Rev# 6406 - bug# 298985 : Refactor Vector usage to Id or CacheId http://fisheye2.atlassian.com/browse/eclipselink/trunk/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/CacheImpl.java?r=6406 20091124: Rev# 5875 - bug# 272895 : Check invalidation during contains() http://fisheye2.atlassian.com/browse/eclipselink/trunk/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/CacheImpl.java?r=5875 20090513: Rev# 4170 - bug# 275953 : Bootstrap performance and compatibility http://fisheye2.atlassian.com/browse/eclipselink/trunk/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/CacheImpl.java?r=4170 >Analysis page discussion at http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/cache_api#Refactor_20100322
Created attachment 163846 [details] 248780 CacheImpl refactor for MappedSuperclass support (based on Doug's analysis) >CacheImpl refactor based on Doug's analysis http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/cache_api#Analysis
>The following bugs are for reference interest and are not blocking Bug# 298985 , Bug# 308114, Bug# 272895, Bug# 275953, Bug# 301063
>see related bug# 308950 JPA2: Merge EntityManagerFactoryImpl.getIdentifier() as subset of CacheImpl.getId() functionality
Created attachment 164715 [details] CacheImpl refactor for MappedSuperclass support including test suite modifications License headers are reverted to original SUN
Created attachment 165763 [details] CacheImpl refactor for MappedSuperclass support including test suite modifications 2
>The following model is used to to illustrate use case behavior when invalidating non-entity classes like MappedSuperclasses or plain java classes at the root or leaf level (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 170855 [details] CacheImpl refactor for MappedSuperclass support including test suite modifications 3
Created attachment 170908 [details] CacheImpl refactor for MappedSuperclass support including test suite modifications 3
>See SVN rev# 7461, 7462 and 7468 http://fisheye2.atlassian.com/changelog/eclipselink/?cs=7461 http://fisheye2.atlassian.com/changelog/eclipselink/?cs=7462 http://fisheye2.atlassian.com/changelog/eclipselink/?cs=7468 >Release notes for [invalidateClass recurse=false functionality modified] http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/cache_api#Release
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink