Shared (L2) Entity Cache
Every EntityManagerjavax.persistence.EntityManager (JPA Interface)Interface 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 EntityManagerjavax.persistence.EntityManager (JPA Interface)Interface used to interact with the persistence context.. This section describes a level 2 (L2) cache of entity objects, which is managed by the EntityManagerFactoryjavax.persistence.EntityManagerFactory (JPA Interface)Interface 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 Cacheablejavax.persistence.Cacheable (JPA Annotation)Specifies 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 Annotation)Specifies 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 Annotation)Specifies 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 Cacheablejavax.persistence.Cacheable (JPA Annotation)Specifies 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 Annotation)Specifies 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 Annotation)Specifies 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 CacheRetrieveModejavax.persistence.CacheRetrieveMode (JPA Enum)Used 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 Enum)Used as the value of the
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 Constant)Read entity data from the cache: this is the default behavior. - cache is used. - CacheRetrieveModejavax.persistence.CacheRetrieveMode (JPA Enum)Used as the value of the
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 Constant)Bypass the cache: get data directly from the database. javax.persistence.CacheRetrieveMode.BYPASS (JPA Enum Constant)Bypass the cache: get data directly from the database.- cache is not used.
The default setting is USEjavax.persistence.CacheRetrieveMode.USE (JPA Enum Constant)Read entity data from the cache: this is the default behavior.. It can be changed for a specific EntityManager
:
em.setProperty( "javax.persistence.cache.retrieveMode", CacheRetrieveModejavax.persistence.CacheRetrieveMode (JPA Enum)Used 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 Constant)Bypass the cache: get data directly from the database.);
Setting can also be overridden for a specific retrieval operation:
// Before executing a query: query.setHint("javax.persistence.cache.retrieveMode", CacheRetrieveModejavax.persistence.CacheRetrieveMode (JPA Enum)Used 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 Constant)Bypass the cache: get data directly from the database.); // For retrieval by type and primary key: em.find(MyEntity2.class, Long.valueOf(1), Collections.<String,Object>singletonMap( "javax.persistence.cache.retrieveMode", CacheRetrieveModejavax.persistence.CacheRetrieveMode (JPA Enum)Used 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 Constant)Bypass 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 CacheStoreModejavax.persistence.CacheStoreMode (JPA Enum)Used 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 Enum)Used 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 Constant)Don't insert into cache. - cache is not updated with new data. - CacheStoreModejavax.persistence.CacheStoreMode (JPA Enum)Used 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..USEjavax.persistence.CacheStoreMode.USE (JPA Enum Constant)Insert entity data into cache when read from database and insert/update entity data when committed into database: this is the default behavior. - new data is stored in the cache - but only for entity objects that are not in the cache already. - CacheStoreModejavax.persistence.CacheStoreMode (JPA Enum)Used 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..REFRESHjavax.persistence.CacheStoreMode.REFRESH (JPA Enum Constant)Insert/update entity data into cache when read from database and when committed into database. - new data is stored in the cache - refreshing entity objects that are already cached.
The default setting is USEjavax.persistence.CacheStoreMode.USE (JPA Enum Constant)Insert 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.setProperty("javax.persistence.cache.storeMode", CacheStoreModejavax.persistence.CacheStoreMode (JPA Enum)Used 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 Constant)Don't insert into cache.);
Setting can also be overridden for a specific retrieval operation. For example:
em.find(MyEntity2.class, Long.valueOf(1), Collections.<String,Object>singletonMap( "javax.persistence.cache.storeMode", CacheRetrieveModejavax.persistence.CacheRetrieveMode (JPA Enum)Used 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 Constant)Don'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 Cachejavax.persistence.Cache (JPA Interface)Interface used to interact with the second-level cache. interface. A Cache
instance can be obtained by using the EntityManagerFactoryjavax.persistence.EntityManagerFactory (JPA Interface)Interface used to interact with the entity manager factory for the persistence unit.'s getCache method:
Cachejavax.persistence.Cache (JPA Interface)Interface used to interact with the second-level cache. cache = emf.getCache();
The Cache
object enables checking if a specified entity object is cached:
boolean isCached = cache.contains(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.evict(MyEntity.class, Long.valueOf(id)); // Remove all the instances of a specific class from the cache: cache.evict(MyEntity.class); // Clear the shared cache by removing all the cached entity objects: cache.evictAll();
The Cachejavax.persistence.Cache (JPA Interface)Interface used to interact with the second-level cache. interface and its methods are unnecessary in most applications.