Spring Boot
JPA2
Hibernate
Second Level Cache
Caching

Spring Boot JPA2 Hibernate - enable second level cache

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Spring Boot, JPA, and Hibernate form a powerful trio for building robust, scalable, and maintainable enterprise applications. In this article, we focus on enabling Hibernate's second-level cache in a Spring Boot application using JPA2. The second-level cache can significantly enhance the application's performance by reducing the number of database queries. Let's dive deep into the concepts, configuration, and implementation details.

Introduction to Hibernate Caching

Hibernate offers two levels of caching:

  1. First-Level Cache: This is sometimes known as the session cache and is enabled by default. It is specific to a session and cannot be shared across different sessions.
  2. Second-Level Cache: This cache is associated with the SessionFactory and is a shared cache. It improves performance by minimizing database access and can be shared across sessions.

Why Use a Second-Level Cache?

  • Reduced Latency: Accessing cached data is faster than querying the database.
  • Improved Scalability: Caching reduces the load on the database, allowing it to handle more users.
  • Cost Savings: Less database interaction means reduced operational costs.

Configuring Second-Level Cache in Spring Boot

To enable second-level caching, consider the following steps:

Step 1: Add Cache Dependency

First, choose an appropriate caching provider. Commonly used caching solutions with Hibernate include EHCache, Infinispan, Hazelcast, etc. For this example, let's use EHCache.

Update your pom.xml or build.gradle to include the EHCache dependency:

Maven:

xml
1<dependency>
2    <groupId>org.hibernate</groupId>
3    <artifactId>hibernate-ehcache</artifactId>
4    <version>5.4.32.Final</version> <!-- Ensure the version matches your Hibernate version -->
5</dependency>

Gradle:

groovy
implementation 'org.hibernate:hibernate-ehcache:5.4.32.Final'

Step 2: Configure Hibernate Caching in application.properties

Enable caching properties in your application.properties or application.yml:

properties
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.jcache.JCacheRegionFactory
spring.jpa.properties.hibernate.cache.use_query_cache=true

Step 3: Define Caching Strategy

Hibernate allows you to specify the caching strategy per entity. Use annotations like @Cacheable and @Cache on entities:

java
1import org.hibernate.annotations.Cache;
2import org.hibernate.annotations.CacheConcurrencyStrategy;
3
4@Entity
5@Cacheable
6@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
7public class Product {
8    @Id
9    private Long id;
10
11    private String name;
12
13    private Double price;
14
15    // Getters and Setters
16}

Step 4: Configure EHCache

Create an ehcache.xml configuration file in src/main/resources:

xml
1<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2         xsi:noNamespaceSchemaLocation="ehcache.xsd"
3         updateCheck="false" monitoring="autodetect" dynamicConfig="true">
4
5    <cache name="productCache"
6           maxEntriesLocalHeap="1000"
7           timeToLiveSeconds="3600">
8    </cache>
9
10    <!-- Default Cache -->
11    <defaultCache
12            maxEntriesLocalHeap="10000"
13            eternal="false"
14            timeToIdleSeconds="600"
15            timeToLiveSeconds="1200"
16            overflowToDisk="false" />
17</ehcache>

Step 5: Testing the Cache

Ensure that the cache is working. You can monitor the cache metrics through logging or use tools like JVisualVM.

In your code, execute queries and check if the subsequent requests fetch data from the cache. Use logging at the debug level to verify this:

properties
logging.level.org.hibernate.cache=DEBUG

Comparison of Cache Providers

Let's compare a few cache providers, focusing on some essential features:

FeatureEHCacheInfinispanHazelcast
ConfigurationXML, ProgrammaticXML, Programmatic, AnnotationsXML, Java, YAML
Setup ComplexityModerateHighModerate
Clustered CachingLimitedYesYes
Memory UsageModerateHighModerate
PersistenceDisk, HeapAdvancedDisk, In-Memory

Conclusion

By enabling Hibernate's second-level cache in a Spring Boot application, developers can significantly enhance application performance through reduced database interactions. While the setup and configuration require some upfront effort, the benefits are clearly visible in high-throughput applications.

Careful selection of a caching provider and knowledge of caching strategies is crucial to success. Experimenting with different configurations and monitoring the performance gains can help in optimizing the cache settings further.

Hibernate second-level caching is a powerful feature that, when combined with Spring Boot and JPA, allows for building agile and high-performing enterprise solutions.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.