Below there are 3 snippest. First is Error , 2nd is Springboot code and 3rd one is pom.xml.
2023-04-03 23:56:25.961 INFO 32460 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2023-04-03 23:56:25.976 INFO 32460 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 3.645 seconds (JVM running for 4.332)
2023-04-03 23:56:26.898 INFO 32460 --- [ main] com.example.demo.DemoApplication : Return the value from the cache: Hello World
2023-04-03 23:56:27.136 INFO 32460 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-04-03 23:56:27.174 ERROR 32460 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771) ~[spring-boot-2.7.10.jar:2.7.10]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:752) ~[spring-boot-2.7.10.jar:2.7.10]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) ~[spring-boot-2.7.10.jar:2.7.10]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-2.7.10.jar:2.7.10]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-2.7.10.jar:2.7.10]
at com.example.demo.DemoApplication.main(DemoApplication.java:39) ~[classes/:na]
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: ERR unknown command `GETEX`, with args beginning with: `testkey`, `ex`, `15`, ; nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR unknown command `GETEX`, with args beginning with: `testkey`, `ex`, `15`,
at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:69) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:42) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:192) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.jedis.JedisConnection.doWithJedis(JedisConnection.java:827) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.jedis.JedisConnection.doInvoke(JedisConnection.java:165) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.jedis.JedisConnection.lambda$new$0(JedisConnection.java:74) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.jedis.JedisInvoker$Synchronizer.invoke(JedisInvoker.java:1018) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.jedis.JedisInvoker.just(JedisInvoker.java:130) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.jedis.JedisStringCommands.getEx(JedisStringCommands.java:84) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.DefaultedRedisConnection.getEx(DefaultedRedisConnection.java:286) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.DefaultStringRedisConnection.getEx(DefaultStringRedisConnection.java:468) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.core.DefaultValueOperations$4.inRedis(DefaultValueOperations.java:109) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:61) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:97) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.core.DefaultValueOperations.getAndExpire(DefaultValueOperations.java:105) ~[spring-data-redis-2.7.10.jar:2.7.10]
at com.example.demo.DemoApplication.run(DemoApplication.java:59) ~[classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:768) ~[spring-boot-2.7.10.jar:2.7.10]
... 5 common frames omitted
Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR unknown command `GETEX`, with args beginning with: `testkey`, `ex`, `15`,
at redis.clients.jedis.Protocol.processError(Protocol.java:142) ~[jedis-3.8.0.jar:na]
at redis.clients.jedis.Protocol.process(Protocol.java:176) ~[jedis-3.8.0.jar:na]
at redis.clients.jedis.Protocol.read(Protocol.java:230) ~[jedis-3.8.0.jar:na]
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:352) ~[jedis-3.8.0.jar:na]
at redis.clients.jedis.Connection.getBinaryBulkReply(Connection.java:289) ~[jedis-3.8.0.jar:na]
at redis.clients.jedis.BinaryJedis.getEx(BinaryJedis.java:465) ~[jedis-3.8.0.jar:na]
at org.springframework.data.redis.connection.jedis.JedisInvoker.lambda$just$5(JedisInvoker.java:130) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.jedis.JedisConnection.lambda$doInvoke$2(JedisConnection.java:181) ~[spring-data-redis-2.7.10.jar:2.7.10]
at org.springframework.data.redis.connection.jedis.JedisConnection.doWithJedis(JedisConnection.java:824) ~[spring-data-redis-2.7.10.jar:2.7.10]
... 20 common frames omitted
package com.example.demo;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
//import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.data.redis.core.ValueOperations;
import ch.qos.logback.core.pattern.Converter;
import ch.qos.logback.core.util.Duration;
@SpringBootApplication
//@ConfigurationProperties
public class DemoApplication implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(DemoApplication.class);
private java.time.Duration duration = java.time.Duration.ofSeconds(15);
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Autowired
private StringRedisTemplate template;
@Override
//@ConfigurationProperties(prefix = "spring.redis")
public void run(String...args) {
ValueOperations < String, String > ops = this.template.opsForValue();
String key = "testkey";
if (!this.template.hasKey(key)) {
ops.set(key, "Hello World", duration);
LOGGER.info("Add a key is done");
}
LOGGER.info("Return the value from the cache: {}", ops.get(key));
LOGGER.info("Return the value from the cache: {}", ops.getAndExpire(key, duration));
String s = ops.getAndExpire(key, 15000, TimeUnit.MILLISECONDS);
//hash functions
HashRepository hashrepo = new HashRepository(template);
String cacheKey = "user";
if (!this.template.hasKey(cacheKey)) {
HashMap < String, String > hashmap = new HashMap < String, String > ();
hashmap.put("rimno", "1");
hashmap.put("accountInfo", "<accounts><accountno>1</accountno></accounts>");
hashrepo.addHashMap(cacheKey, hashmap);
LOGGER.info("Add a hashmap is done");
} else {
hashrepo.updateHashValue(cacheKey, "name", "mynane1");
hashrepo.updateHashValue(cacheKey, "accountInfo", "<accounts><accountno>2</accountno></accounts>");
LOGGER.info(String.format("retrieved accountInfo with value %s", hashrepo.getHashValue(cacheKey, "accountInfo")));
}
LOGGER.info("Return the value from the cache: {}", hashrepo.getHashMap(cacheKey));
}
}
class HashRepository {
final Logger logger = LoggerFactory.getLogger(HashRepository.class);
private HashOperations < String, String, String > hashOperations;
private StringRedisTemplate template;
public HashRepository(StringRedisTemplate template) {
this.template = template;
this.hashOperations = template.opsForHash();
}
public void addHashMap(String cacheKey, Map < String, String > data) {
hashOperations.putAll(cacheKey, data);
logger.info(String.format("Data with cachekey %s saved", cacheKey));
}
public void updateHashValue(String cacheKey, String hashKey, String data) {
hashOperations.put(cacheKey, hashKey, data);
logger.info(String.format("Data with hashkey %s update", hashKey));
}
public String getHashValue(String cacheKey, String hashKey) {
String s = (String) hashOperations.get(cacheKey, hashKey);
logger.info(String.format("Data retrieved with hashkey %s", s));
return s;
}
public Map < String, String > getHashMap(String cacheKey) {
return hashOperations.entries(cacheKey);
}
public void deleteHashMap(String cacheKey) {
template.delete(cacheKey);
logger.info(String.format("Map with cacheKey %s deleted", cacheKey));
}
}
@Configuration
class MyConfig {
@Autowired
private Environment environment;
@Bean
JedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(
"xyz.redis.cache.windows.net",
6379
);
configuration.setPassword(environment.getProperty("spring.redis.password"));
return new JedisConnectionFactory(configuration);
}
@Bean
StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
<?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.7.10</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot With Redis Cache</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
GETEX
is a new command only available from Redis 6.2 and above.
The best approach is to upgrade, 2nd best would be to wrap a GET
and an EXPIRE
command in a single [transaction][1].
MULTI
GET <key>
EXPIRE <key> <seconds>
EXEC