The Level 1 cache is used within the PersistenceManager/EntityManager, storing objects that are currently managed etc. There are several implementations of Level 1 Cache here :- SoftRefCache, WeakRefCache and HardRefCache. They provide varying degrees of object retention during the garbage collection process.
The Level 2 cache is used across multiple PersistenceManagers/EntityManagers within the same PersistenceManagerFactory/EntityManagerFactory. There are several implementations of a Level 2 Cache here :- JavaxCacheLevel2Cache (using the javax.cache API), SoftLevel2Cache, and WeakLevel2Cache. Alternatively look in the datanucleus-cache plugin for various L2 caches using third party software.
As far as Level 2 caching is concerned each class is configurable via metadata @Cacheable (and equivalent XML) as to whether it is cached. In addition we can define which fields are cacheable using this mechanism, but maybe using @Extension metadata if the persistence API doesn't support field-level restrictions.
At commit of a transaction we check all enlisted objects and have a recursive process that navigates down through all objects to cache (limited by the FetchPlan) and at the end all of these objects will be put in the L2 cache (and logged). Also at this point if any enlisted objects have been deleted during the transaction we remove them from the L2 cache. When an object is to be put in the L2 cache we check if it already has an entry in the L2 cache and, if so, we update that object with the current field values, version, etc. When an object is to be put in the L2 cache and it has relation fields, we don't store the actual objects of those relations instead storing the identities of the related objects in the CachedPC object. When an object is to be taken from the L2 cache we create a copy of that object and copy the field values across for all fields that were loaded when it was originally put in the cache. When a relation field is required to be loaded we use the identities that are stored in the CachedPC, and find the equivalent object for that identity from the L1/L2 caches, reinstating it into the managed object.
Interface Summary Interface Description Level1CacheProvides an interface for Level 1 caches. Level2CacheInterface for any Level 2 Cache used internally.
Class Summary Class Description AbstractLevel2CacheAbstract starting point for a third-party L2 cache plugin. AbstractReferencedLevel2CacheAbstract referenced implementation of a Level 2 cache, to be used as the base for weak/soft variants. CachedPCAn object that is stored in the Level2 Cache keyed by the identity of the persistable object. CachedPC.CachedId CacheUniqueKeyKey representing a unique key for a persistable object. JavaxCacheLevel2CacheSimple implementation of a plugin for use of javax.cache (v0.61+) product with DataNucleus. L2CachePopulateFieldManagerFieldManager responsible for populating the provided CachedPC object. L2CacheRetrieveFieldManagerFieldManager responsible for retrieving the values from the provided CachedPC object. NullLevel2CacheNull implementation of a Level 2 Cache. SoftLevel2CacheSoft implementation of a Level 2 cache. SoftRefCacheLevel 1 Cache using Soft referenced objects in a Map. StrongRefCacheImplementation of a Level 1 cache keeping strong references to the objects. WeakLevel2CacheWeak referenced implementation of a Level 2 cache. WeakRefCacheLevel 1 Cache using Weak referenced objects in a Map.