# Creating an implementaion of L2 cache for hibernate based on Redis

**URL:** https://discourse.hibernate.org/t/creating-an-implementaion-of-l2-cache-for-hibernate-based-on-redis/8950
**Category:** Hibernate ORM
**Created:** [February 1, 2024, 10:52am UTC](https://discourse.hibernate.org/t/creating-an-implementaion-of-l2-cache-for-hibernate-based-on-redis/8950 "2024-02-01T10:52:29Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![rixterd2](https://avatars.discourse-cdn.com/v4/letter/r/96bed5/32.png) [@rixterd2](https://discourse.hibernate.org/u/rixterd2)
#### Post date: [February 1, 2024, 10:52am UTC](https://discourse.hibernate.org/t/creating-an-implementaion-of-l2-cache-for-hibernate-based-on-redis/8950/1 "2024-02-01T10:52:29Z")

</div>

Greetings,

My goal is to create L2 cache based on Redis without JTA support. I apologize if this question was asked previously, though I didn’t find any on hibernate forum.

To begin with there is almost no guidelines how or where to start. I analyzed dozens of articles, github repositories and read 3 books on Redis itself about caching and it’s strategies. In the end I’ve started to read through hibernate cache SPI [hibernate-orm/hibernate-core/src/main/java/org/hibernate/cache/spi at main · hibernate/hibernate-orm · GitHub](https://github.com/hibernate/hibernate-orm/tree/main/hibernate-core/src/main/java/org/hibernate/cache/spi)

There are number of access interfaces : CollectionDataAccess, EntityDataAccess, NaturalIdDataAccess, CachedDomainDataAccess. These interfaces are meant to be a “Contract for managing transactional and concurrent access”. Under the hood hibernate implementation uses StorageAccess interface to access L2 cache, which is also working with transactional access and non-transactional for eviction.

First question. Am I right to understand that CollectionDataAccess, EntityDataAccess, NaturalIdDataAccess, CachedDomainDataAccess are responsible for “application” wide transactions (has nothing to do with the L2 Cache) and StorageAccess is responsible for transactional access to L2 Cache (Redis) itself ? Can I rely on implementations provided by hibernate for CollectionDataAccess, EntityDataAccess, NaturalIdDataAccess, CachedDomainDataAccess ?

We have different AccessType variants [hibernate-orm/hibernate-core/src/main/java/org/hibernate/cache/spi/access/AccessType.java at main · hibernate/hibernate-orm · GitHub](https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core/src/main/java/org/hibernate/cache/spi/access/AccessType.java)

Second question, probably a newbie one. The doc is clear about NONSTRICT\_READ\_WRITE and READ\_ONLY. Though it forces engineer to question what are “soft” and “hard” locks in terms of TRANSACTIONAL and READ\_WRITE access. Assuming that I have multiple instances of an “application” which use L2 Cache(Redis). Am I right that “soft” lock is one which resides inside L2 Cache (Redis) and “hard” lock is a kind of JTA feature of enterprise grade server like WildFly ?

Thank you !

Regards,  
rixterd2

---

<div class="post-metadata">

### Author: ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)
#### Post date: [February 2, 2024, 10:31am UTC](https://discourse.hibernate.org/t/creating-an-implementaion-of-l2-cache-for-hibernate-based-on-redis/8950/2 "2024-02-02T10:31:22Z")

</div>

The cache does not have to be transactional and you don’t need to support JTA if you want to write a customer cache integration, though you should probably rather use the [Redis JCache implementation](https://github.com/redisson/redisson/tree/master/redisson/src/main/java/org/redisson/jcache) and stick to Hibernate ORMs JCache integration module or use the [Redisson Hibernate ORM integration](https://github.com/redisson/redisson/tree/master/redisson-hibernate).

---

<div class="post-metadata">

### Author: ![rixterd2](https://avatars.discourse-cdn.com/v4/letter/r/96bed5/32.png) [@rixterd2](https://discourse.hibernate.org/u/rixterd2)
#### Post date: [February 2, 2024, 11:53am UTC](https://discourse.hibernate.org/t/creating-an-implementaion-of-l2-cache-for-hibernate-based-on-redis/8950/3 "2024-02-02T11:53:56Z")

</div>

Hello, Christian !

Thank you for the reply !

Unfortunately hibernate uses javax for JCache module and we are moving away to jakarta 10. By the way are there any plans/roadmaps on jakarta migration for this module ?

I’m surprised that we can avoid synchronization on cache with hibernate. Can you please share your thoughts on that ?

Let’s for example take AccessType.READ\_WRITE and multiple “services” sharing the same L2 cache. I thought that it will require some kind locking inside L2 cache just to ensure that we always have consistent state of shared entities. Obviously I’m mistaken if you’re saying that cache does not have to be transactional. How does hibernate preserve data consistency when using shared ( among different application instances ) L2 cache then ?

How do I avoid : modify (instance 1) → get & cache (instance 2 ) → cache invalidation (instance 1) ? Data consistency is broken in such scenarios.

P.S\> My colleague has found implementation of a lock for READ\_WRITE access inside hibernate [hibernate-orm/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractReadWriteAccess.java at main · hibernate/hibernate-orm · GitHub](https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractReadWriteAccess.java#L346)  
I thought it should be on a cache provider side 🙂

Regards,  
rixterd2

---

<div class="post-metadata">

### Author: ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)
#### Post date: [February 5, 2024, 10:27am UTC](https://discourse.hibernate.org/t/creating-an-implementaion-of-l2-cache-for-hibernate-based-on-redis/8950/4 "2024-02-05T10:27:47Z")

</div>

> Unfortunately hibernate uses javax for JCache module and we are moving away to jakarta 10. By the way are there any plans/roadmaps on jakarta migration for this module ?

JCache is not part of Jave/Jakarta EE and never transitioned to the jakarta namespace.

> Let’s for example take AccessType.READ\_WRITE and multiple “services” sharing the same L2 cache. I thought that it will require some kind locking inside L2 cache just to ensure that we always have consistent state of shared entities. Obviously I’m mistaken if you’re saying that cache does not have to be transactional. How does hibernate preserve data consistency when using shared ( among different application instances ) L2 cache then ?

> How do I avoid : modify (instance 1) → get & cache (instance 2 ) → cache invalidation (instance 1) ? Data consistency is broken in such scenarios.

This is usually avoided by creating a sort of “tombstone” entry for a particular cache key, which has a certain TTL, though I am no expert in this area. I guess [hibernate-orm/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractReadWriteAccess.java at main · hibernate/hibernate-orm · GitHub](https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core/src/main/java/org/hibernate/cache/spi/support/AbstractReadWriteAccess.java#L346) that you found is exactly about that.

> I thought it should be on a cache provider side 🙂

Since most cache providers don’t support participating in a transaction, Hibernate ORM implements this through such means.
