Hibernate Tutorial

Core Hibernate

Hibernate Mapping

Hibernate Annotations

Hibernate with Spring Framework

Hibernate with Database

Hibernate Log4j

Inheritance Mapping

Hibernate - Caching

Caching is an optimization technique that stores frequently accessed data in memory, so the application doesn't have to retrieve the data from the database every time. Hibernate offers caching mechanisms to boost the performance of applications and reduce database traffic.

In Hibernate, there are two main levels of caching:

  1. First Level Cache (Session Cache):

    • Enabled by default.
    • Associated with the Hibernate Session.
    • Lives only as long as the session.
    • Any object loaded in a session is cached in the session cache and can be retrieved without hitting the database again during the session's lifetime.
  2. Second Level Cache (SessionFactory Cache):

    • Optional and can be set up using third-party caching providers like EHCache, Hazelcast, etc.
    • Associated with the Hibernate SessionFactory.
    • Lives as long as the SessionFactory, i.e., the entire application's lifecycle.
    • Shared across multiple sessions.

1. First Level Cache:

Since it's enabled by default, any object you fetch using a Hibernate session is cached in the first-level cache.

Example:

Session session = sessionFactory.openSession();

// This will hit the database
Student student1 = session.get(Student.class, 1);

// This will NOT hit the database; student2 is fetched from the session cache
Student student2 = session.get(Student.class, 1);

session.close();

To clear the first-level cache manually, you can use:

session.clear(); // clears the cache for the entire session

Or, to evict a particular object:

session.evict(student1);

2. Second Level Cache:

To set up and use the second-level cache:

Step 1: Add the necessary dependencies. For this example, we'll use EHCache:

<!-- EHCache core library -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.6</version>
</dependency>

<!-- Hibernate EHCache integration -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>5.4.32.Final</version>
</dependency>

Step 2: Configure Hibernate to use EHCache in hibernate.cfg.xml:

<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

Step 3: Annotate your entity to be cacheable:

@Entity
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Student {
    // ... entity fields and methods ...
}

Here, we used a READ_ONLY cache strategy, which is suitable for data that doesn't change. You might choose other strategies like READ_WRITE depending on your use-case.

Step 4: Optional, but advisable, configure EHCache settings in an ehcache.xml file:

<ehcache>

    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="600"
        overflowToDisk="true">
    </defaultCache>

    <cache name="com.example.Student"
           maxElementsInMemory="1000"
           eternal="false"
           timeToIdleSeconds="300"
           timeToLiveSeconds="600"
           overflowToDisk="true"/>
</ehcache>

With this in place, Hibernate will utilize the second-level cache to store Student entities. When you request a Student object in any session, Hibernate will first check the second-level cache before hitting the database.

Important Points:

  1. Use Caching Judiciously: Not all data is suitable for caching. Cache data that's frequently read but rarely modified.

  2. Concurrency Strategy: Choose the right cache concurrency strategy (READ_ONLY, READ_WRITE, NONSTRICT_READ_WRITE, TRANSACTIONAL) based on your application needs.

  3. Monitor Your Cache: Use monitoring tools to measure cache hit/miss ratios and tweak your cache settings accordingly.

  4. Cache Eviction and Expiration: Understand how and when data is removed from the cache. Stale data can lead to application inconsistencies.

  5. Query Cache: Apart from entity caching, Hibernate also provides a query cache to cache the results of frequently executed queries.

Caching can significantly boost the performance of your application, but it also adds complexity. Ensure you thoroughly test the behavior and performance implications of caching in your application.

  1. Configuring caching in Hibernate:

    Configure caching in Hibernate to improve performance by reducing the number of database queries.

    <!-- Enable second-level cache in hibernate.cfg.xml -->
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
    
  2. Enabling and disabling caching in Hibernate:

    Enable or disable caching at the entity level in Hibernate.

    @Entity
    @Cacheable // Enable caching for this entity
    public class Product {
        // Entity properties and methods
    }
    
    <!-- Disable caching for this entity in hbm.xml -->
    <class name="Product" table="products" dynamic-insert="false" dynamic-update="false" select-before-update="false">
        <cache usage="nonstrict-read-write" include="false"/>
        <!-- Entity mapping details -->
    </class>
    
  3. Using query caching in Hibernate:

    Hibernate query caching improves performance by caching the results of queries.

    Query query = session.createQuery("FROM Product WHERE category = :category");
    query.setParameter("category", "Electronics");
    query.setCacheable(true); // Enable query caching
    List<Product> products = query.list();
    
  4. Cache providers in Hibernate:

    Hibernate supports various cache providers. Example using Ehcache:

    <!-- Configure Ehcache as the cache provider in hibernate.cfg.xml -->
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
    

    Ensure you include the Ehcache library in your project.