Caching - rafalkieras/jpa-kss GitHub Wiki

#Caching

##First level cache

Persistence context act as a first level cache for entities. It is associated with every EntityManager instance and it cannot be disabled.

To check if the instance is associated with the current persistence context you can use EntityManager#contains method.

To remove the entity from the first level cache you can use EntityManager#detach method. This will cause that the entity will not be managed by the EntityManager.

##Second level cache

The second level cache is shared across all EntityManager instances for the given persistence unit. It is application wide cache. It is disabled by default, it can be enabled in the persistence.xml configuration file.

Persistence providers are not required to support a second-level cache. Portable applications should not rely on support by persistence providers for a second-level cache.

In order to enable second level cache, you need to specify the cache mode in persistence.xml via shared-cache-mode element. It can have following values:

  • ALL - All entity data is stored in the second-level cache for this persistence unit.
  • NONE - No data is cached in the persistence unit. The persistence provider must not cache any data.
  • ENABLE_SELECTIVE - Enable caching for entities that have been explicitly set with the @Cacheable annotation.
  • DISABLE_SELECTIVE - Enable caching for all entities except those that have been explicitly set with the @Cacheable(false) annotation.
  • UNSPECIFIED - The caching behavior for the persistence unit is undefined. The persistence provider’s default caching behavior will be used.

To control whether an entity should be cached or not the @Cacheable annotations is used. If applied on a class it also takes effect on subclasses. It may be overriden on the subclass level by placing the annotation on the subclass itself.

The Cache interface can be used to interact with the second-level cache. It can be obtained from EntityManagerFactory#getCache method. To get EntityManagerFactory from EntityManager use EntityManager#getEntityManagerFactory.

It is possible to control interaction with cache via the following properties:

  • javax.persistence.cache.storeMode - accepts values of CacheStoreMode enum.
  • javax.persistence.cache.retrieveMode - accepts values of CacheRetrieveMode enum.

##Query cache

JPA specification does not say anything about query cache. If you want to use query cache you need to use provider specific properties.

Anyway it does not mean that queries does not interact with second level cache. To populate the second-level cache with query result use query hints:

entityManager.createQuery("from Employee")
    .setHint("javax.persistence.cache.storeMode", CacheStoreMode.REFRESH)