📜 ⬆️ ⬇️

Hibernate Developer Documentation - Chapter VI. Caching

I present to you the translation of the sixth chapter of the official documentation Hibernate .

Article translation is relevant for the version Hibernate 4.2.19.Final

Previous Chapter - Hibernate Developer Documentation - Chapter V. Locks
')
What is the first and second level cache in Hibernate is shown in the following diagram ( author’s note ).

image

6.1. Query cache


If you have requests running again and again, with the same parameters, query caching will provide a performance benefit.

Caching introduces additional overhead in the transaction area. For example, if you are caching the results of a query with respect to an object, Hibernate needs to monitor whether any changes have been committed to the object, and accordingly, invalidate the cache entries. In addition, the benefits of query caching are limited, and are highly dependent on the usage patterns of your application. For these reasons, Hibernate by default turns off query caching.

Procedure 6.1. Allow query caching


  1. Set the hibernate.cache.use_query_cache property to true .

    This setting will create two new caching regions:

    • org.hibernate.cache.internal.StandardQueryCache stores the results of cached queries.
    • org.hibernate.cache.spi.UpdateTimestampsCache stores the timestamps of recent updates in the requested tables. These timestamps validate the results taken from the query cache (i.e., they are used to verify the relevance of the objects).

  2. Configure caching region timeout

    If you configure timeouts or expiration in your cache implementation, set the underlying cache region timeout for UpdateTimestampsCache to a greater value than the timeout of any of the query caches. It is possible, and recommended, to set an infinite expiration timeout for the UpdateTimestampsCache region. More specifically, the LRU caching policy (Least Recently Used) is not considered appropriate.
  3. Allow caching results for specific queries.

    Since most requests do not benefit from caching, you only need to allow caching for individual requests, even after ubiquitous caching is enabled. To enable caching for a particular query, call org.hibernate.Query.setCacheable (true) . The call will allow the query "look" in the cache before execution, or put the results there after execution.

The query cache does not cache the state of the actual entities in the cache. It caches identifier values ​​and type results. Thus, always use the query cache paired with the second-level cache for those entities that should be cached as part of the query cache.

6.1.1. Query cache regions


To better control the expiration policies of query caches, specify a named caching region for a particular query by calling Query.setCacheRegion () .

Example 6.1. SetCacheRegion method

List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger") .setEntity("blogger", blogger) .setMaxResults(15) .setCacheable(true) .setCacheRegion("frontpages") .list(); 

To force the query cache to update one of its regions, and ignore any cached data, call org.hibernate.Query.setCacheMode (CacheMode.REFRESH) . Paired with the region defined for the query, Hibernate selectively updates the results cached in the region. This is more efficient than bulk deletion of bulk records from a region using org.hibernate.SessionFactory.evictQueries () .

6.2. L2 Cache Providers


Hibernate is compatible with some second-tier cache providers. None of the providers support absolutely all possible caching strategies defined in Hibernate. Section 6.2.3, “Second-Level Cache Providers for Hibernate” contains a list of providers, along with their interfaces and supported caching strategies. For definitions of caching strategies, see Section 6.2.2, “Caching Strategies” .

6.2.1. Custom Cache Providers Configuration


You can configure your cache providers using annotations or mapping files. Entities, by default, are not part of the second-level cache, and their use is not recommended. If you still need to use entities, set the shared-cache-mode element in persistence.xml , or use the javax.persistence.sharedCache.mode property in your configuration. Use one of the values ​​in Table 6.1, “Possible Values ​​for Shared Cache Mode” .

Table 6.1. Possible values ​​for Shared Cache Mode
ValueDescription
ENABLE_SELECTIVEEntities will not be cached until you explicitly mark them as cacheable.
This value is recommended and used by default.
DISABLE_SELECTIVEEntities will be cached until you explicitly cancel caching on them.
ALLAll entities will be cached, regardless of whether you mark them as non-cacheable.
NoneNo entity will be cached, even if you mark them as cacheable. This option cancels
job cache second level.

The global concurrency strategy is set using the hibernate.cache.default_cache_concurrency_strategy property. See possible values ​​in section 6.2.2, “Caching Strategies” .

Important
When possible, define concurrency caching strategies only for a specific entity, but not globally. Use the @ org.hibernate.annotations.Cache annotation.

Example 6.2. Configure cache providers using annotations.
 @Entity @Cacheable @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) public class Forest { ... } 

You can cache the contents of collections or identifiers if the collection contains other entities. Use the @Cache annotation on the collection property.

@Cache contains several attributes.

Attributes of the @Cache annotation:
NameDescription
usageThe given concurrency cache strategy, which can be:
  • None
  • READ_ONLY
  • NONSTRICT_READ_WRITE
  • READ_WRITE
  • TRANSACTIONAL

regionCaching region This attribute is optional, and by default it matches the full name of the class, or
role role of the collection.
includeInclude or not all properties. Optional, and can take two possible values.
  • All - all properties are included. Used by default.
  • The non-lazy value includes only non-lazy properties.



Example 6.3. Configuration of cache providers using mapping files.
 <cache usage="transactional" region="RegionName" include="all" /> 

As in Example 6.2, “Configuring cache providers using annotations,” you can specify attributes in the mapping files. There are several specific differences in the syntax of attributes in the mapping files.
NameDescription
usageCaching strategy This attribute is required and can be any of the following values:
  • transactional
  • read-write
  • nonstrict-read-write
  • read-only

regionThe name of the second-level cache region. By default, matches the full class name or role collection name.
includeCan entity properties specified with lazy = true be cached when enabled
“Lazy” sampling at the attribute level. Default is all and may also be non-lazy

Instead of cache , you can use the elements class-cache , collection-cache in hibernate.cfg.xml .

6.2.2. Caching strategies



6.2.3. Hibernate Providers for L2 Cache


CacheSupported Strategies
HashTable (only for tests)
  • read-only
  • nonstrict read-write
  • read-write
EHCache
  • read-only
  • nonstrict read-write
  • read-write
  • transactional
Infinispan
  • read-only
  • transactional

6.3. Cache management


6.3.1. Add / retrieve cache entries


Actions that add entries to the internal session cache:
Saving or updating entityExtract entity
  • save ()
  • update ()
  • saveOrUpdate ()
  • load ()
  • get ()
  • list ()
  • iterate ()
  • scroll ()

Synchronize or delete cached entry. The state of the object is synchronized with the database when you call the flush () method. To avoid synchronization, you can remove the object and its collections from the first-level cache using the evict () method. To remove all entries from the session cache, use the Session.clear () method.

Example 6.4. Deleting entries from the first level cache
 ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set while ( cats.next() ) { Cat cat = (Cat) cats.get(0); doSomethingWithACat(cat); sess.evict(cat); } 

How to determine whether an entity belongs to the session cache . The Session object provides the contains () method to determine whether the object belongs to the session cache.

Example 6.5 Removing a second-level cache
You can remove the cached state of an entity, the entire class, collection, or all role collection using the methods of SessionFactory
 sessionFactory.getCache().containsEntity(Cat.class, catId); // is this particular Cat currently in the cache sessionFactory.getCache().evictEntity(Cat.class, catId); // evict a particular Cat sessionFactory.getCache().evictEntityRegion(Cat.class); // evict all Cats sessionFactory.getCache().evictEntityRegions(); // evict all entity data sessionFactory.getCache().containsCollection("Cat.kittens", catId); // is this particular collection currently in the cache sessionFactory.getCache().evictCollection("Cat.kittens", catId); // evict a particular collection of kittens sessionFactory.getCache().evictCollectionRegion("Cat.kittens"); // evict all kitten collections sessionFactory.getCache().evictCollectionRegions(); // evict all collection data 


6.3.1.2. View Secondary Cache and Query Caches


After statistics are enabled, you can view the contents of the second-level cache or caching region.

Procedure 6.2. Resolving statistics
  1. Set hibernate.generate_statistics to true .
  2. Optional - set hibernate.cache.use_structured_entries to true so that Hibernate can store records in a format that the user can understand.


Example 6.6. View L2 Cache via Statistics API
 Map cacheEntries = sessionFactory.getStatistics() .getSecondLevelCacheStatistics(regionName) .getEntries(); 

Source: https://habr.com/ru/post/268747/


All Articles