clint
clint

Reputation: 1946

Issue in Second Level Caching + Spring Boot + Java Hibernate

Added following in pom.xml:

<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
</dependency>

Then, Following in the Customer Repository

@Cacheable(cacheNames="customer", key="#email")
@Query(value = "select company_name from  customer  where email =?1", nativeQuery = true)
List<String> getUserByEmailID(String emailID);

Given following in the app.prop file:

spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
spring.jpa.properties.javax.persistence.sharedCache.mode=ALL

Added following in the customer entity:

@Cacheable
@org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "customer")
public class Customer implements Serializable {

..}

Code for which caching is required:

List<String> ibCustomers = customerRepository.getUserByEmailID("[email protected]");

My aim is the implement second level caching with query, which means if second time same query is created, the query should not execute. Right now, the query is getting fired always even though, i gave same email, as i see this in log every time:

org.hibernate.SQL                        : 
    /* dynamic native SQL query */ select
        company_name 
    from
        customer  
    where
        email =?

What am i doing wrong??

Upvotes: 0

Views: 1285

Answers (1)

Angelo Immediata
Angelo Immediata

Reputation: 6944

You can use or JPA caching (I guess @Cacheable is related to JPA) or Hibernate caching so you should consider 2 scenarios.

JPA scenario

In the case of JPA: according to JPA specification in order to enable JPA caching (is @Cacheable the JPA annotation?) you must specify the <shared-cache-mode> in your persistence.xml

For example:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
  <persistence-unit name="SimpleTest" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
    </properties>
  </persistence-unit>
</persistence>

Hibernate Scenario

In case you use the hibernate caching you must use the @Cache annotation provided by Hibernate (Hibernate @Cache)

Moreover if you use a hibernate Query object you must specify that the query should be cached by doing something like this:

Query q = hibSession.createQuery(....);
q.setCacheable(true);

You can find more here https://www.baeldung.com/hibernate-second-level-cache

I hope this is useful

Upvotes: 1

Related Questions