example - spring-data-redis redisTemplate Exception
spring-boot-starter-data-redis (2)
Cuando llamo al método get (), ocurrió una excepción
aquí está el código
@Service("RedisService")
public class RedisServiceImpl implements RedisService {
@Autowired
RedisTemplate<String, Long> redisTemplate;
@Override
public Long get(String key) {
return redisTemplate.opsForValue().get(key);
}
@Override
public Long incrBy(String key, long increment) {
return redisTemplate.opsForValue().increment(key, increment);
}
cuando uso el método incrBy, no hay excepciones pero solo los errores solo obtienen el método
aquí está la stacktrace ---
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2280)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2749)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:779)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)
at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:38)
at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:58)
at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:1)
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:40)
at org.springframework.data.redis.core.AbstractOperations.deserializeValue(AbstractOperations.java:198)
at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:50)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:162)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:133)
at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:84)
at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:42)
at net.daum.air21.bot.common.service.RedisServiceImpl.get(RedisServiceImpl.java:29)
at net.daum.air21.bot.user.service.SeraCoffeeServiceImpl.getCurrentCount(SeraCoffeeServiceImpl.java:41)
De forma predeterminada, RedisTemplate utiliza un JdkSerializationRedisSerializer, por lo que si hiciera un "conjunto", su Long se vería así en Redis:
"/xac/xed/x00/x05sr/x00/x0ejava.lang.Long;/x8b/xe4/x90/xcc/x8f#/xdf/x02/x00/x01J/x00/x05valuexr/x00/x10java.lang.Number/x86/xac/x95/x1d/x0b/x94/xe0/x8b/x02/x00/x00xp/x00/x00/x00/x00/x00/x00/x00/x04"
IncrBy funciona porque Redis siempre devuelve un largo desde esa operación, por lo que RedisTemplate no intenta deserializar el resultado. El resultado de "obtener", sin embargo, pasa por el proceso de deserialización, que espera un formato como el anterior.
Puede resolver esto usando un serializador de valor diferente en su RedisTemplate:
redisTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
O pruebe la clase RedisAtomicLong que viene con spring-data-redis.
Poco frustrante, gracias por el consejo sobre RedisAtomicLong ... pero aquí hay una solución para usar HashOps con String Key, String field y Long value: usa Spring Boot para facilitar la configuración
@SpringBootApplication
@Configuration
public class DemoApplication {
public static void main(String[] args) {
final ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
final DacRepository dacRepository = context.getBean(DacRepository.class);
dacRepository.incrKeyExample();
}
@Bean
public RedisTemplate<String, Long> getLongRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
final RedisTemplate<String,Long> redisTemplate = new RedisTemplate<String, Long>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setHashValueSerializer(new GenericToStringSerializer<Long>(Long.class));
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class DacRepository {
private final HashOperations<String, String, Long> hashOps;
@Autowired
private final RedisTemplate<String, Long> redisTemplate;
@Autowired
public DacRepository(RedisTemplate<String, Long> redisTemplate) {
this.redisTemplate = redisTemplate;
hashOps = redisTemplate.opsForHash();
}
public void incrKeyExample() {
final Set<String> keys = this.redisTemplate.keys("*");
for(String key: keys) {
System.out.println("key: "+ key);
}
final String key = "deal-1";
final String field = "view";
final Long value = 1L;
hashOps.put(key, field, value);
final Long delta = 1L;
hashOps.increment(key, field, delta);
Long val = hashOps.get("deal-1", "view");
System.out.println("Value = "+val);
}
}
server.port=9001
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1