Hibernate Second-Level cache with EhCache

Seonggil Jeong
4 min readSep 10, 2022

--

The time and cost to access the database over the network is much more expensive than the time to access the server’s internal memory.
In this article, I will explain how to reduce the number of database accesses by caching data in memory.

Overview

As with most other fully-equipped ORM frameworks, Hibernate has the concept of a first-level cache.
In this article we’ll explore Hibernate second-level cache.

Also, I will explain the difference between the second-level cache and the first-level

What is ORM(Object-Relational Mapping)?

Object-relational mapping (ORM) is a programming technique in which a metadata descriptor is used to connect object code to a relational database.
Table : Entity (1:1)

ORM(Object-Relational Mapping)

Hibernate is one of the ORM frameworks

About first-level cache

With JPA, first-level cache is applied by default
It’s a session scoped cache which ensures that each entity instance is loaded only once in the persistent context

first-level cache
  1. Search information by user2 ID value
    userRepository.findById(“userId”)
  2. If there is information in the cache, the value of the cache is returned.
    If not, the information is retrieved from the DB.
    SELECT * FROM USER_INFO WHERE USER_ID = #{userId}
  3. Value save in the cache and returns it
  • When spring runs, it doesn’t save all of data,
    only records per row are cached when select, update delete, save
  • Once the session is closed, the first-level cache is terminated as well. This is actually desirable, as it allows for concurrent sessions to work with entity instances in isolation from each other.

About second-level cache

Conversely, a second-level cache is SessionFactory-scoped
meaning it’s shared by all sessions created with the same session factory.

second-level cache
  1. Since there is no Entity in the second-level Cache at the time of the first inquiry, it is queried from the DB.
  2. Save the result in the second-level Cache, returns a copy of Entity
  3. When looking up the same entity, it returns a copy of the entity from the second-level cache.

Why use a second-level cache?

The second-level cache provides a copy of the query results to the persistence context.
The reason is that even if multiple users modify the entity in first-level cache, it does not affect the second-level cache to be actually reflected.

This can be used to maximize concurrency.

Concurrency is a method for operating multi-threads on a single core, and refers to the property of multiple threads running alternately for multi-tasking. Single-core multitasking using concurrency looks like each thread is running in parallel, but in fact, they are running little by little in turn.

How to use second-level cache?

java : 1.8

pom.xml
application.yml## Enable @Cacheable annotation
spring.jpa.properties.javax.persistence.sharedCache.mode = ENABLE_SELECTIVE
## Enable second-level cache.
spring.jpa.properties.hibernate.cache.use_second_level_cache = true
## Specifies the class to handle the second-level cache.
spring.jpa.properties.hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.EhCacheRegionFactory
## Check whether the cache is applied
spring.jpa.properties.hibernate.generate_statistics = true
resources/ehcache.xml

.xml file can be used to set Cache preferences, More settings are possible

ItemEntity.java

After adding the Cacheable annotation, you are all set to enable secondary cache
Check out the results now

  • first request
    findById(1)
firstRequest

1 misses because there is no value in cache And
Save the value fetched from DB in the cache

  • second request (same Entity)
    findById(1)
secondRequest

1 hits because there is a value in the cache

--

--