Shared (L2) Entity Cache
Every EntityManagerjakarta.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 EntityManagerjakarta.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 EntityManagerFactoryjakarta.persistence.EntityManagerFactory - JPA Interface Interface used to interact with the persistence unit, and to create new instances of EntityManager. 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 CacheUsing the Shared CacheUsing the Cache InterfaceSetting the Shared Cache
The shared (L2) cache is configured in three scopes:
- Globally in the ObjectDB configuration.
- Per persistence unit in the
persistence.xmlfile. - 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 theUNSPECIFIEDvalue 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 Cacheablejakarta.persistence.Cacheable - JPA Annotation Specifies whether an entity should be cached, if caching is enabled, and when the value of the {@code persistence.xml} caching element is SharedCacheMode#ENABLE_SELECTIVE or SharedCacheMode#DISABLE_SELECTIVE. explicitly. For example:
@Cacheablejakarta.persistence.Cacheable - JPA Annotation Specifies whether an entity should be cached, if caching is enabled, and when the value of the {@code persistence.xml} caching element is SharedCacheMode#ENABLE_SELECTIVE or SharedCacheMode#DISABLE_SELECTIVE. // or @Cacheable(true) @Entityjakarta.persistence.Entity - JPA Annotation Declares that the annotated 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 Cacheablejakarta.persistence.Cacheable - JPA Annotation Specifies whether an entity should be cached, if caching is enabled, and when the value of the {@code persistence.xml} caching element is SharedCacheMode#ENABLE_SELECTIVE or SharedCacheMode#DISABLE_SELECTIVE. explicitly. For example:
@Cacheablejakarta.persistence.Cacheable - JPA Annotation Specifies whether an entity should be cached, if caching is enabled, and when the value of the {@code persistence.xml} caching element is SharedCacheMode#ENABLE_SELECTIVE or SharedCacheMode#DISABLE_SELECTIVE.(false) @Entityjakarta.persistence.Entity - JPA Annotation Declares that the annotated 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 CacheRetrieveModejakarta.persistence.CacheRetrieveMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database via the EntityManager#find methods and execution of queries. enum:
- CacheRetrieveModejakarta.persistence.CacheRetrieveMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database via the EntityManager#find methods and execution of queries..USEjakarta.persistence.CacheRetrieveMode.USE - JPA Enum Constant Read entity data from the cache: this is the default behavior. - cache is used.
- CacheRetrieveModejakarta.persistence.CacheRetrieveMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database via the EntityManager#find methods and execution of queries..BYPASSjakarta.persistence.CacheRetrieveMode.BYPASS - JPA Enum Constant Bypass the cache: get data directly from the database. jakarta.persistence.CacheRetrieveMode.BYPASS - JPA Enum Constant Bypass the cache: get data directly from the database.- cache is not used.
The default setting is USEjakarta.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.setPropertyEntityManager.setProperty(propertyName,value) - JPA Method Set an entity manager property or hint.( "javax.persistence.cache.retrieveMode", CacheRetrieveModejakarta.persistence.CacheRetrieveMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database via the EntityManager#find methods and execution of queries..BYPASSjakarta.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.setHintTypedQuery.setHint(hintName,value) - JPA Method Set a query property or hint.("javax.persistence.cache.retrieveMode", CacheRetrieveModejakarta.persistence.CacheRetrieveMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database via the EntityManager#find methods and execution of queries..BYPASSjakarta.persistence.CacheRetrieveMode.BYPASS - JPA Enum Constant Bypass the cache: get data directly from the database.); // For retrieval by type and primary key: em.findEntityManager.find(entityClass,primaryKey,properties) - JPA Method Find by primary key, using the specified properties.(MyEntity2.class, Long.valueOf(1), Collections.<String,Object>singletonMap( "javax.persistence.cache.retrieveMode", CacheRetrieveModejakarta.persistence.CacheRetrieveMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database via the EntityManager#find methods and execution of queries..BYPASSjakarta.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 CacheStoreModejakarta.persistence.CacheStoreMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database and when data is written to the database. enum:
- CacheStoreModejakarta.persistence.CacheStoreMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database and when data is written to the database..BYPASSjakarta.persistence.CacheStoreMode.BYPASS - JPA Enum Constant Don't insert into cache. - cache is not updated with new data.
- CacheStoreModejakarta.persistence.CacheStoreMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database and when data is written to the database..USEjakarta.persistence.CacheStoreMode.USE - JPA Enum Constant Insert entity data into cache when read from database and insert/update entity data when written to the 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.
- CacheStoreModejakarta.persistence.CacheStoreMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database and when data is written to the database..REFRESHjakarta.persistence.CacheStoreMode.REFRESH - JPA Enum Constant Insert/update entity data held in the cache when read from the database and when written to the database. - new data is stored in the cache - refreshing entity objects that are already cached.
The default setting is USEjakarta.persistence.CacheStoreMode.USE - JPA Enum Constant Insert entity data into cache when read from database and insert/update entity data when written to the database: this is the default behavior.. It can be changed for a specific EntityManager:
em.setPropertyEntityManager.setProperty(propertyName,value) - JPA Method Set an entity manager property or hint.("javax.persistence.cache.storeMode", CacheStoreModejakarta.persistence.CacheStoreMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database and when data is written to the database..BYPASSjakarta.persistence.CacheStoreMode.BYPASS - JPA Enum Constant Don't insert into cache.);
Setting can also be overridden for a specific retrieval operation. For example:
em.findEntityManager.find(entityClass,primaryKey,properties) - JPA Method Find by primary key, using the specified properties.(MyEntity2.class, Long.valueOf(1), Collections.<String,Object>singletonMap( "javax.persistence.cache.storeMode", CacheRetrieveModejakarta.persistence.CacheRetrieveMode - JPA Enum Specifies how the EntityManager interacts with the second-level cache when data is read from the database via the EntityManager#find methods and execution of queries..BYPASSjakarta.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 Cachejakarta.persistence.Cache - JPA Interface Interface used to interact with the second-level cache. interface. A Cache instance can be obtained by using the EntityManagerFactoryjakarta.persistence.EntityManagerFactory - JPA Interface Interface used to interact with the persistence unit, and to create new instances of EntityManager.'s getCacheEntityManagerFactory.getCache() - JPA Method Access the cache that is associated with the entity manager factory (the "second level cache"). method:
Cachejakarta.persistence.Cache - JPA Interface Interface used to interact with the second-level cache. cache = emf.getCacheEntityManagerFactory.getCache() - JPA Method Access 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 Method Whether the cache contains data for the given entity.Cache.contains(cls,primaryKey) - JPA Method Whether 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 Method Remove the data for the given entity from the cache.Cache.evict(cls,primaryKey) - JPA Method Remove 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 Method Remove the data for entities of the specified class (and its subclasses) from the cache.Cache.evict(cls) - JPA Method Remove 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 Method Clear the cache.();
The Cachejakarta.persistence.Cache - JPA Interface Interface used to interact with the second-level cache. interface and its methods are unnecessary in most applications.