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.FinalPrevious 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 ).

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
- 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).
- 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.
- 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 methodList 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 ModeValue | Description |
---|
ENABLE_SELECTIVE | Entities will not be cached until you explicitly mark them as cacheable. This value is recommended and used by default. |
DISABLE_SELECTIVE | Entities will be cached until you explicitly cancel caching on them. |
ALL | All entities will be cached, regardless of whether you mark them as non-cacheable. |
None | No 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” .
ImportantWhen 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:Name | Description |
---|
usage | The given concurrency cache strategy, which can be:
- None
- READ_ONLY
- NONSTRICT_READ_WRITE
- READ_WRITE
- TRANSACTIONAL
|
region | Caching region This attribute is optional, and by default it matches the full name of the class, or role role of the collection. |
include | Include 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.
Name | Description |
---|
usage | Caching strategy This attribute is required and can be any of the following values:
- transactional
- read-write
- nonstrict-read-write
- read-only
|
region | The name of the second-level cache region. By default, matches the full class name or role collection name. |
include | Can 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
- read-only
Read-only cache is good for data that is read but not changed. A simple, well-functioning approach that is also safe in a clustered environment. - nonstrict read-write
Some applications only need to read the data occasionally. This is the case when two transactions are unlikely to simultaneously update the same entity. In such a case, you do not need to limit transaction isolation, and the nonstrict-read-write cache is quite appropriate. If the cache is used in a JTA environment, you must specify hibernate.transaction.manager_lookup_class . In other environments, make sure that the transaction is completed before calling Session.close () or Session.disconnect () .
- read-write
The read-write cache is suitable for applications where data is updated regularly. Do not use the read-write strategy if you need serializable transaction isolation. In the JTA environment, specify the strategy for getting the JTA TransactionManager by setting the hibernate.transaction.manager_lookup_class property. In non-JTA environments, be sure to complete the transaction before calling Session.close () or Session.disconnect () .
ImportantTo use read-write strategies in a clustered environment, the underlying cache implementation must support locks. Built-in cache providers do not support locks.
- transactional
Transactional caching strategy provides support for transactional cache providers, such as JBoss TreeCache. You can only use such a cache in a JTA environment, and first you need to specify hibernate.transaction.manager_lookup_class .
6.2.3. Hibernate Providers for L2 Cache
Cache | Supported Strategies |
---|
HashTable (only for tests) | - read-only
- nonstrict read-write
- read-write
|
EHCache | - read-only
- nonstrict read-write
- read-write
- transactional
|
Infinispan | |
6.3. Cache management
6.3.1. Add / retrieve cache entries
Actions that add entries to the internal session cache:
Saving or updating entity | Extract 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();
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 cacheYou 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);
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- Set hibernate.generate_statistics to true .
- 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();