I'm learning redis. Now facing a problem with redis cache. I'm calling a method of a service class with same value but it seems it is executed each time.
When I am calling getEmployeesByClient() method of EmployeeService from ThreadService I am expecting for a new client I will see the log Inside of getEmployeeByClient. But for next calling I will get list from cache, then it will not give data from repository.
But I'm getting the log Inside of getEmployeeByClient each time I'm calling the method getEmployeesByClient() of EmployeeService with same argument. I have provided my log as well at the end of this section.
I have seen some questions of this site like this: Spring boot caching in @Service class does not work
But have not got solution.
I'm providing my related codes:
My ThreadService class:
@Service
@Slf4j
public class ThreadService implements Runnable {
@Autowired
private EmployeeService employeeService;
public static boolean isRunning = true;
@PostConstruct
@Override
public void run() {
log.debug("Service Thread Started");
while(isRunning) {
log.debug("repository calling...");
List<Employee> employees = employeeService.getEmployeesByClient("FastVoiz");
log.debug("Employee Size: " + employees.size());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
log.error("Exception: ", e);
}
}
}
}
EmployeeService class:
@Service
@Slf4j
public class EmployeeService {
@Autowired
private EmployeeRepository repository;
@Cacheable(value = "employeeCache", key = "#client")
public List<Employee> getEmployeesByClient(String client) {
log.debug("Inside of getEmployeeByClient");
return repository.findEmployeesByClient(client);
}
}
RedisConfiguration class:
@Configuration
@EnableCaching
@PropertySource("classpath:application.properties")
public class RedisConfiguration {
@Autowired
private Environment env;
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisConf = new RedisStandaloneConfiguration();
redisConf.setHostName(env.getProperty("spring.redis.host"));
redisConf.setPort(Integer.parseInt(env.getProperty("spring.redis.port")));
redisConf.setPassword(RedisPassword.of(env.getProperty("spring.redis.password")));
return new LettuceConnectionFactory(redisConf);
}
@Bean
public RedisCacheConfiguration cacheConfiguration() {
RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.disableCachingNullValues();
return cacheConfig;
}
@Bean
public RedisCacheManager cacheManager() {
RedisCacheManager rcm = RedisCacheManager.builder(redisConnectionFactory())
.cacheDefaults(cacheConfiguration())
.transactionAware()
.build();
return rcm;
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demoNaz</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demoNaz</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<maven.test.skip>true</maven.test.skip>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!--to run jar file-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<finalName>demoNaz</finalName>
</build>
</project>
application.properties file:
#JPA configuration
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.show-sql=true
spring.data.jpa.repositories.enabled=true
spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.id.new_generator_mappings=false
spring.jpa.properties.hibernate.format_sql=true
#datasource
spring.datasource.url=jdbc:postgresql://localhost:5432/testDB
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.initialization-mode=always
#spring.datasource.initialize=true
#spring.datasource.schema=classpath:/schema.sql
spring.datasource.continue-on-error=true
spring.datasource.platform=postgres
#redis
spring.redis.host=localhost
spring.redis.timeout=2000
spring.redis.password=password
spring.redis.port=6379
#redis cache manager configuration
spring.cache.type=redis
spring.cache.redis.cache-null-values=false
spring.cache.redis.time-to-live=600000
spring.cache.redis.use-key-prefix=true
#redis-lettuce configuration
spring.redis.lettuce.pool.max-active=7
spring.redis.lettuce.pool.max-idle=7
spring.redis.lettuce.pool.min-idle=2
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.shutdown-timeout=200ms
#logging
logging.level.root=DEBUG
logging.file=demoApp.log
#others
spring.main.allow-bean-definition-overriding=true
Here is my some log:
2019-10-13 20:17:29.619 DEBUG 12932 --- [ main] c.example.demoNaz.service.ThreadService : First line of thread
2019-10-13 20:17:29.619 DEBUG 12932 --- [ main] c.e.demoNaz.service.EmployeeService : Inside of getEmployeeByClient
2019-10-13 20:17:29.620 DEBUG 12932 --- [ main] tor$SharedEntityManagerInvocationHandler : Creating new EntityManager for shared EntityManager invocation
2019-10-13 20:17:29.620 DEBUG 12932 --- [ main] o.h.q.c.internal.CriteriaQueryImpl : Rendered criteria query -> select generatedAlias0 from Employee as generatedAlias0 where generatedAlias0.client=:param0
2019-10-13 20:17:29.620 DEBUG 12932 --- [ main] org.hibernate.SQL : select employee0_.id as id1_0_, employee0_.acc as acc2_0_, employee0_.client as client3_0_ from employee employee0_ where employee0_.client=?
Hibernate: select employee0_.id as id1_0_, employee0_.acc as acc2_0_, employee0_.client as client3_0_ from employee employee0_ where employee0_.client=?
2019-10-13 20:17:29.622 DEBUG 12932 --- [ main] org.hibernate.loader.Loader : Result set row: 0
2019-10-13 20:17:29.622 DEBUG 12932 --- [ main] org.hibernate.loader.Loader : Result row: EntityKey[com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:29.622 DEBUG 12932 --- [ main] o.h.engine.internal.TwoPhaseLoad : Resolving associations for [com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:29.622 DEBUG 12932 --- [ main] o.h.engine.internal.TwoPhaseLoad : Done materializing entity [com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:29.623 DEBUG 12932 --- [ main] c.example.demoNaz.service.ThreadService : Employee Size: 1
2019-10-13 20:17:32.258 DEBUG 12932 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Pool stats (total=10, active=0, idle=10, waiting=0)
2019-10-13 20:17:34.623 DEBUG 12932 --- [ main] c.example.demoNaz.service.ThreadService : First line of thread
2019-10-13 20:17:34.624 DEBUG 12932 --- [ main] c.e.demoNaz.service.EmployeeService : Inside of getEmployeeByClient
2019-10-13 20:17:34.625 DEBUG 12932 --- [ main] tor$SharedEntityManagerInvocationHandler : Creating new EntityManager for shared EntityManager invocation
2019-10-13 20:17:34.625 DEBUG 12932 --- [ main] o.h.q.c.internal.CriteriaQueryImpl : Rendered criteria query -> select generatedAlias0 from Employee as generatedAlias0 where generatedAlias0.client=:param0
2019-10-13 20:17:34.627 DEBUG 12932 --- [ main] org.hibernate.SQL : select employee0_.id as id1_0_, employee0_.acc as acc2_0_, employee0_.client as client3_0_ from employee employee0_ where employee0_.client=?
Hibernate: select employee0_.id as id1_0_, employee0_.acc as acc2_0_, employee0_.client as client3_0_ from employee employee0_ where employee0_.client=?
2019-10-13 20:17:34.628 DEBUG 12932 --- [ main] org.hibernate.loader.Loader : Result set row: 0
2019-10-13 20:17:34.629 DEBUG 12932 --- [ main] org.hibernate.loader.Loader : Result row: EntityKey[com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:34.630 DEBUG 12932 --- [ main] o.h.engine.internal.TwoPhaseLoad : Resolving associations for [com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:34.630 DEBUG 12932 --- [ main] o.h.engine.internal.TwoPhaseLoad : Done materializing entity [com.example.demoNaz.entity.Employee#13002]
2019-10-13 20:17:34.631 DEBUG 12932 --- [ main] c.example.demoNaz.service.ThreadService : Employee Size: 1
2019-10-13 20:17:39.633 DEBUG 12932 --- [ main] c.example.demoNaz.service.ThreadService : First line of thread
2019-10-13 20:17:39.633 DEBUG 12932 --- [ main] c.e.demoNaz.service.EmployeeService : Inside of getEmployeeByClient