Shared (L2) Entity Cache
Every EntityManager
javax.persistence.EntityManager - JPA InterfaceInterface used to interact with the persistence context. owns a persistence context, which is a collection of all the entity objects that it manages. The persistence context serves as a first level cache. An attempt to retrieve an entity object that is already managed by the EntityManager
returns the existing instance from the persistence context, rather than a newly instantiated entity object.
The scope of the persistence context is one EntityManager
javax.persistence.EntityManager - JPA InterfaceInterface used to interact with the persistence context.. This section describes a level 2 (L2) cache of entity objects, which is managed by the EntityManagerFactory
javax.persistence.EntityManagerFactory - JPA InterfaceInterface used to interact with the entity manager factory for the persistence unit. and shared by all its EntityManager
objects. the broader scope of this cache makes it useful in applications that use many short term EntityManager
instances.
In addition to the EntityManager
's L1 cache and the EntityManagerFactory
's L2 cache, which are managed on the client side - ObjectDB manages also several caches on the server side:
- Cache of database file pages.
- Cache of query programs.
- Cache of query execution results.
The scope of these server side caches is wider, since they exist per database and are shared by all the EntityManagerFactory
and EntityManager
instances of the same database - including on different client machines.
This page covers the following topics:
Setting the Shared Cache
The shared (L2) cache is configured in three scopes:
- Globally in the ObjectDB configuration.
- Per persistence unit in the
persistence.xml
file. - Per entity class - using annotations.
ObjectDB Configuration
The shared cache size is specified in the ObjectDB configuration:
<cache ... level2="0mb" />
The level2
attribute determines the size of the EntityManagerFactory
's shared cache. The default size, 0
, indicates that the cache is disabled. To enable the cache a positive value has to be specified.
Persistence Unit Settings
The shared cache can also be enabled or disabled using a persistence unit property:
<persistence-unit name="my-pu"> ... <properties> <property name="javax.persistence.sharedCache.mode" value="ALL"/> </properties> ... </persistence-unit>
The javax.persistence.sharedCache.mode
property can be set to one of the following values:
NONE
- cache is disabled.ENABLE_SELECTIVE
- cache is disabled except for selected entity classes (see below).DISABLE_SELECTIVE
- cache is enabled except for selected entity classes (see below).ALL
(the default) - cache is enabled for all the entity classes.UNSPECIFIED
- handled differently by different JPA providers. In ObjectDB theUNSPECIFIED
value is equivalent toALL
, which is the default.
If the cache size is 0
- the shared cache is disabled regardless of the set mode.
Entity Class Cache Settings
The ENABLE_SELECTIVE
mode indicates that the cache is disabled for all the entity classes except classes that are specified as Cacheable
javax.persistence.Cacheable - JPA AnnotationSpecifies whether an entity should be cached if caching is enabled when the value of the persistence.xml
caching element is ENABLE_SELECTIVE
or DISABLE_SELECTIVE
. explicitly. For example:
@Cacheablejavax.persistence.Cacheable - JPA AnnotationSpecifies whether an entity should be cached if caching is enabled when the value of thepersistence.xml
caching element isENABLE_SELECTIVE
orDISABLE_SELECTIVE
. // or @Cacheable(true) @Entityjavax.persistence.Entity - JPA AnnotationSpecifies that the class is an entity. public class MyCacheableEntityClass { ... }
Similarly, the DISABLE_SELECTIVE
value indicates that the cache is enabled for all the entity classes except classes that are specified as non Cacheable
javax.persistence.Cacheable - JPA AnnotationSpecifies whether an entity should be cached if caching is enabled when the value of the persistence.xml
caching element is ENABLE_SELECTIVE
or DISABLE_SELECTIVE
. explicitly. For example:
@Cacheablejavax.persistence.Cacheable - JPA AnnotationSpecifies whether an entity should be cached if caching is enabled when the value of thepersistence.xml
caching element isENABLE_SELECTIVE
orDISABLE_SELECTIVE
.(false) @Entityjavax.persistence.Entity - JPA AnnotationSpecifies that the class is an entity. public class MyNonCacheableEntityClass extends MyCacheableEntityClass { ... }
Cacheable
is an inherited property - every entity class which is not marked with @Cacheable
inherits cacheability setting from its super class.
Using the Shared Cache
The shared cache (when enabled) provides the following functionality automatically:
- On retrieval - shared cache is used for entity objects that are not in the persistence context. If an entity object is not available also in the shared cache - it is retrieved from the database and added to the shared cache.
- On commit - new and modified entity objects are added to the shared cache.
JPA provides two properties that can be used in order to change the default behavior.
javax.persistence.cache.retrieveMode
The "javax.persistence.cache.retrieveMode"
property specifies if the shared cache is used on retrieval. Two values are available for this property as constants of the CacheRetrieveMode
javax.persistence.CacheRetrieveMode - JPA EnumUsed as the value of the javax.persistence.cache.retrieveMode
property to specify the behavior when data is retrieved by the find
methods and by queries. enum:
CacheRetrieveModejavax.persistence.CacheRetrieveMode - JPA EnumUsed as the value of the
- cache is used.javax.persistence.cache.retrieveMode
property to specify the behavior when data is retrieved by thefind
methods and by queries..USEjavax.persistence.CacheRetrieveMode.USE - JPA Enum ConstantRead entity data from the cache: this is the default behavior.CacheRetrieveModejavax.persistence.CacheRetrieveMode - JPA EnumUsed as the value of the
javax.persistence.CacheRetrieveMode.BYPASS - JPA Enum ConstantBypass the cache: get data directly from the database.- cache is not used.javax.persistence.cache.retrieveMode
property to specify the behavior when data is retrieved by thefind
methods and by queries..BYPASSjavax.persistence.CacheRetrieveMode.BYPASS - JPA Enum ConstantBypass the cache: get data directly from the database.
The default setting is USE
javax.persistence.CacheRetrieveMode.USE - JPA Enum ConstantRead entity data from the cache: this is the default behavior.. It can be changed for a specific EntityManager
:
em.setPropertyEntityManager.setProperty(propertyName,value) - JPA MethodSet an entity manager property or hint.( "javax.persistence.cache.retrieveMode", CacheRetrieveModejavax.persistence.CacheRetrieveMode - JPA EnumUsed as the value of thejavax.persistence.cache.retrieveMode
property to specify the behavior when data is retrieved by thefind
methods and by queries..BYPASSjavax.persistence.CacheRetrieveMode.BYPASS - JPA Enum ConstantBypass the cache: get data directly from the database.);
Setting can also be overridden for a specific retrieval operation:
// Before executing a query: query.setHintTypedQuery.setHint(hintName,value) - JPA MethodSet a query property or hint.("javax.persistence.cache.retrieveMode", CacheRetrieveModejavax.persistence.CacheRetrieveMode - JPA EnumUsed as the value of thejavax.persistence.cache.retrieveMode
property to specify the behavior when data is retrieved by thefind
methods and by queries..BYPASSjavax.persistence.CacheRetrieveMode.BYPASS - JPA Enum ConstantBypass the cache: get data directly from the database.); // For retrieval by type and primary key: em.findEntityManager.find(entityClass,primaryKey,properties) - JPA MethodFind by primary key, using the specified properties.(MyEntity2.class, Long.valueOf(1), Collections.<String,Object>singletonMap( "javax.persistence.cache.retrieveMode", CacheRetrieveModejavax.persistence.CacheRetrieveMode - JPA EnumUsed as the value of thejavax.persistence.cache.retrieveMode
property to specify the behavior when data is retrieved by thefind
methods and by queries..BYPASSjavax.persistence.CacheRetrieveMode.BYPASS - JPA Enum ConstantBypass the cache: get data directly from the database.));
javax.persistence.cache.storeMode
The "javax.persistence.cache.storeMode"
property specifies if new data should be added to the cache on commit and on retrieval. The property has three valid values, which are defined as constants of the CacheStoreMode
javax.persistence.CacheStoreMode - JPA EnumUsed as the value of the javax.persistence.cache.storeMode
property to specify the behavior when data is read from the database and when data is committed into the database. enum:
CacheStoreModejavax.persistence.CacheStoreMode - JPA EnumUsed as the value of the
- cache is not updated with new data.javax.persistence.cache.storeMode
property to specify the behavior when data is read from the database and when data is committed into the database..BYPASSjavax.persistence.CacheStoreMode.BYPASS - JPA Enum ConstantDon't insert into cache.CacheStoreModejavax.persistence.CacheStoreMode - JPA EnumUsed as the value of the
- new data is stored in the cache - but only for entity objects that are not in the cache already.javax.persistence.cache.storeMode
property to specify the behavior when data is read from the database and when data is committed into the database..USEjavax.persistence.CacheStoreMode.USE - JPA Enum ConstantInsert entity data into cache when read from database and insert/update entity data when committed into database: this is the default behavior.CacheStoreModejavax.persistence.CacheStoreMode - JPA EnumUsed as the value of the
- new data is stored in the cache - refreshing entity objects that are already cached.javax.persistence.cache.storeMode
property to specify the behavior when data is read from the database and when data is committed into the database..REFRESHjavax.persistence.CacheStoreMode.REFRESH - JPA Enum ConstantInsert/update entity data into cache when read from database and when committed into database.
The default setting is USEjavax.persistence.CacheStoreMode.USE - JPA Enum ConstantInsert entity data into cache when read from database and insert/update entity data when committed into database: this is the default behavior.. It can be changed for a specific EntityManager
:
em.setPropertyEntityManager.setProperty(propertyName,value) - JPA MethodSet an entity manager property or hint.("javax.persistence.cache.storeMode", CacheStoreModejavax.persistence.CacheStoreMode - JPA EnumUsed as the value of the
javax.persistence.cache.storeMode
property to specify
the behavior when data is read from the database and when data is
committed into the database..BYPASSjavax.persistence.CacheStoreMode.BYPASS - JPA Enum ConstantDon't insert into cache.);
Setting can also be overridden for a specific retrieval operation. For example:
em.findEntityManager.find(entityClass,primaryKey,properties) - JPA MethodFind by primary key, using the specified properties.(MyEntity2.class, Long.valueOf(1), Collections.<String,Object>singletonMap( "javax.persistence.cache.storeMode", CacheRetrieveModejavax.persistence.CacheRetrieveMode - JPA EnumUsed as the value of thejavax.persistence.cache.retrieveMode
property to specify the behavior when data is retrieved by thefind
methods and by queries..BYPASSjavax.persistence.CacheStoreMode.BYPASS - JPA Enum ConstantDon't insert into cache.));
The difference between CacheStoreMode.USE
and CacheStoreMode.REFRESH
is when bypassing the cache in retrieval operations. In this case, an entity object that is already cached is updated using the freshly retrieved data only when CacheStoreMode.REFRESH
is used. This might be useful when the database might be updated by other applications (or using other EntityManagerFactory
instances).
Using the Cache Interface
The shared cache is represented by the Cache
javax.persistence.Cache - JPA InterfaceInterface used to interact with the second-level cache. interface. A Cache
instance can be obtained by using the EntityManagerFactoryjavax.persistence.EntityManagerFactory - JPA InterfaceInterface used to interact with the entity manager factory
for the persistence unit.'s getCacheEntityManagerFactory.getCache() - JPA MethodAccess the cache that is associated with the entity manager
factory (the "second level cache"). method
:
Cachejavax.persistence.Cache - JPA InterfaceInterface used to interact with the second-level cache. cache = emf.getCacheEntityManagerFactory.getCache() - JPA MethodAccess the cache that is associated with the entity manager factory (the "second level cache").();
The Cache
object enables checking if a specified entity object is cached:
boolean isCached = cache.containsCache.contains(cls,primaryKey) - JPA MethodWhether the cache contains data for the given entity.(MyEntity.class, Long.valueOf(id));
Cached entity objects can be removed from the cache by one of the evict
methods:
// Remove a specific entity object from the shared cache: cache.evictCache.evict(cls,primaryKey) - JPA MethodRemove the data for the given entity from the cache.(MyEntity.class, Long.valueOf(id)); // Remove all the instances of a specific class from the cache: cache.evictCache.evict(cls) - JPA MethodRemove the data for entities of the specified class (and its subclasses) from the cache.(MyEntity.class); // Clear the shared cache by removing all the cached entity objects: cache.evictAllCache.evictAll() - JPA MethodClear the cache.();
The Cachejavax.persistence.Cache - JPA InterfaceInterface used to interact with the second-level cache. interface and its methods are unnecessary in most applications.