Hibernate Tutorial

Core Hibernate

Hibernate Mapping

Hibernate Annotations

Hibernate with Spring Framework

Hibernate with Database

Hibernate Log4j

Inheritance Mapping

Hibernate - Cache Expiration

In Hibernate, cache expiration refers to the process where cached data is deemed stale and is no longer considered valid. After expiration, the next request for that data will fetch fresh data from the database. Cache expiration is essential for maintaining data consistency, especially when you have a cache that lasts longer than a single session.

This tutorial focuses on cache expiration in the context of Hibernate's second-level cache, as the first-level cache (Session Cache) lives only as long as the session and doesn't typically involve expiration settings.

1. Set Up:

To demonstrate cache expiration, we'll use EHCache as our caching provider, as it's widely used and integrates well with Hibernate.

You'll need to have the following Maven dependencies:

<!-- 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>

2. Configure Hibernate to Use EHCache:

In your hibernate.cfg.xml or equivalent:

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

3. Enable Caching for Entities:

In your entity class, annotate it as cacheable:

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

For this example, we're using a READ_ONLY strategy for simplicity. Adjust accordingly based on your use-case.

4. Configuring Cache Expiration:

To set cache expiration, configure EHCache in the 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>

Here, timeToIdleSeconds specifies the time after which a cache element is considered idle if it hasn't been accessed. timeToLiveSeconds specifies the total time after which an element is considered expired, irrespective of the last access time.

In the above config:

  • A Student entity in the cache will be considered idle and removed if not accessed for 300 seconds.
  • A Student entity in the cache will be expired and removed after 600 seconds since it was put in the cache, even if it's frequently accessed.

5. Test Cache Expiration:

After setting up, you can test the cache behavior. Here's a simplistic flow:

  1. Fetch a Student entity. As it's the first request, it will hit the database.
  2. Wait for more than 300 seconds but less than 600 seconds.
  3. Fetch the same Student entity again. It should be retrieved from the cache, as the cache is still valid.
  4. Wait until a total of more than 600 seconds has passed since the initial fetch.
  5. Fetch the Student entity again. This time, it should hit the database since the cache has expired.

Note:

Using caching improves performance but introduces complexity. Ensure you understand the implications of caching data, especially in terms of consistency. Use monitoring tools to keep an eye on cache hits, misses, and evictions to tune the cache settings for optimum performance and data accuracy.

  1. Hibernate second-level cache expiration example:

    Hibernate second-level cache expiration involves setting a time limit for how long cached data remains valid.

    SessionFactory sessionFactory = configuration.buildSessionFactory();
    Statistics stats = sessionFactory.getStatistics();
    stats.setStatisticsEnabled(true);
    
    // Enable cache expiration
    sessionFactory.getCache().evictEntityRegion(MyEntity.class);
    
  2. Configuring cache expiration in Hibernate:

    Configure cache expiration settings in Hibernate to control how long cached data remains valid.

    <!-- Configure cache expiration 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>
    <property name="hibernate.cache.ehcache.timeToLiveSeconds">60</property>
    
  3. Time-to-live and idle-time settings for Hibernate cache:

    Set time-to-live (maximum age) and idle-time (maximum time without access) settings for cached entities or collections.

    <!-- Configure time-to-live and idle-time 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>
    <property name="hibernate.cache.ehcache.timeToLiveSeconds">60</property>
    <property name="hibernate.cache.ehcache.timeToIdleSeconds">30</property>
    
  4. Cache region expiration policies in Hibernate:

    Cache regions in Hibernate can have different expiration policies, such as ETERNAL, TIME_TO_LIVE, and MAX_IDLE.

    <!-- Configure cache region expiration policies 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>
    <property name="hibernate.cache.ehcache.expiration">5000</property>
    
  5. Programmatic cache expiration in Hibernate:

    Programmatically expire cached entities or collections based on certain conditions.

    SessionFactory sessionFactory = configuration.buildSessionFactory();
    Cache cache = sessionFactory.getCache();
    
    if (condition) {
        cache.evictEntityRegion(MyEntity.class);
    } else {
        cache.evictCollectionRegion(MyEntity.class.getName() + ".myCollection");
    }
    
  6. Handling cache expiration events in Hibernate:

    Hibernate provides events and listeners to handle cache expiration events and perform custom actions.

    // Implement a cache region factory that supports listeners
    public class CustomEhCacheRegionFactory extends EhCacheRegionFactory {
        @Override
        public void start(SessionFactoryOptions settings, Map properties) {
            super.start(settings, properties);
    
            // Add custom cache event listeners
            getCacheManager().addListener(new CustomCacheEventListener());
        }
    }
    
    // Implement a custom cache event listener
    public class CustomCacheEventListener implements CacheEventListener {
        // Handle cache expiration events
    }
    
  7. Evicting expired entries from Hibernate cache:

    Evict entries from the cache manually if they have expired.

    SessionFactory sessionFactory = configuration.buildSessionFactory();
    sessionFactory.getCache().evictExpiredEntities();