Hibernate 2nd level cache with Redis shared amongst multiple JVMS

I have to use Redis as 2nd level cache in my jvm application. There are multiple instances of the jvms application and all have to use same 2nd level cache instance of redis.
Is it supported by hibernate to share common 2nd level cache across JVMs.
If yes then how data update in one jvm is reflected in other jvms.

That’s the purpose of a 2nd level cache. Here is an article explaining how to setup redis as 2nd level cache: Caching in Hibernate With Redis - DZone Java

1 Like

Thanks @beikov . I am running multiple instance of microservices having hibernate as ORM and all are pointing to same instance of Redis as second level cache using Redisson library.

But as the JVM goes down the cache gets cleared. Is there a property in hibernate that i can set to stop 2level cache clear on JVM shut down.

The second level cache literally is your Redis instance. There is no reason for Hibernate to clear that cache. I don’t know your setup, but I can tell you that this should work as you expect.

1 Like

@beikov. Shared second level cache is behaving as not expected in some scenario.

My set up is:

Multiple instances of same java application are running with shared redis 2nd level cache.
There are 2 entites Employee with one to many with Items:

@Data
@Entity
@Cache(region = "employeeCache", usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee {
	@Id
	private Long id;
	private String firstName;
	
	@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name="employee_id")
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	private Set<Items> items;

.....
}

I want both the entities to be in cache so added @Cache in the relationship.
Now somehow Items table is update in background so i refresh the cache by calling below code in one of the instances of java applications.:

entityManagerFactory.getCache().evict(Items.class, id);
entityManagerFactory.getCache().evict(Employee.class, id);

Now when find the Employee using employeeRepository.findById(id) in the same java instance i get the correct data.

But when i find the same employee object in other java instance it fails with exception that item with id(which was removed) is not found.

How this can be tackled. There are multiple instances of the microservice sharing same cache. If one instance changes anything other doesn’t cope up.

But when i find the same employee object in other java instance it fails with exception that item with id(which was removed) is not found.

What do you mean by removed? If you remove an entity/row, you will obviously not be able to retrieve that anymore as Hibernate will also remove the element from the cache automatically. If by remove you mean evict from the cache, then you will have to ask the maintainers of the Redis second level cache implementation about this. What exception do you get? Usually, when the second level cache does not contain the element Hibernate queries the database. So either your expectation as to how caching should work is wrong or there is a problem in the Redis second level cache implementation.