I am using Spring Data Redis with Jedis. I am trying to store a hash with key vc:${list_id}
. I was able to successfully insert to redis. However, when I inspect the keys using the redis-cli, I don't see the key vc:501381
. Instead I see \xac\xed\x00\x05t\x00\tvc:501381
.
Why is this happening and how do I change this?
You have to serialize teh objects that you are sending it to redis. Below is the complete running example of it. It uses interface
DomainObject
asSerializable
Below are the steps
1) make your maven pom.xml with following jars
2) make your configuration xml as follows
3) Make your classes as follows
For more reference on sprinf jedis you can see http://www.javacodegeeks.com/2012/06/using-redis-with-spring.html
Sample Code is taken from http://javakart.blogspot.in/2012/12/spring-data-redis-hello-world-example.html
Ok, googled around for a while and found help at http://java.dzone.com/articles/spring-data-redis.
It happened because of Java serialization.
The key serializer for redisTemplate needs to be configured to
StringRedisSerializer
i.e. like this:Now the key in redis is
vc:501381
.Or like @niconic says, we can also set the default serializer itself to the string serializer as follows:
which means all our keys and values are strings. Notice however that this may not be preferable, since you may want your values to be not just strings.
If your value is a domain object, then you can use Jackson serializer and configure a serializer as mentioned here i.e. like this:
and configure your template as:
Use
StringRedisTemplate
to replaceRedisTemplate
.By default,
RedisTemplate
uses Java serialization,StringRedisTemplate
usesStringRedisSerializer
.I know this question has been a while, but I did some research on this topic again recently, so I would like to share how this "semi-hashed" key is generated by going thru part of the spring source code here.
First of all, Spring leverages AOP to resolve annotations like
@Cacheable, @CacheEvict or @CachePut
etc. The advice class isCacheInterceptor
from Spring-context dependency, which is a subclass ofCacheAspectSupport
(also from Spring-context). For the ease of this explanation, I would use@Cacheable
as an example to go thru part of the source code here.When the method annotated as
@Cacheable
is invoked, AOP would route it to this methodprotected Collection<? extends Cache> getCaches(CacheOperationInvocationContext<CacheOperation> context, CacheResolver cacheResolver)
fromCacheAspectSupport
class, in which it would try to resolve this@Cacheable
annotation. In turn, it leads to the invocation of this methodpublic Cache getCache(String name)
in the implementing CacheManager. For this explanation, the implementing CacheManage would beRedisCacheManager
(from Spring-data-redis dependency).If the cache was not hit, it will go ahead to create the cache. Below is the key methods from
RedisCacheManager
:Essentially, it will instantiate an
RedisCache
object. To do this, it requires 4 parameters, namely, cacheName, prefix (this is the key parameter with regards to answering this question), redisOperation (aka, the configured redisTemplate), expiration (default to 0) and cacheNullValues (default to false). The constructor below shows more details about RedisCache.So what the use of
prefix
in this RedisCache? --> As shown in the constructor about, it is used in this statementthis.cacheMetadata = new RedisCacheMetadata(name, prefix);
, and the constructor ofRedisCacheMetadata
below shows more details:At this point, we know that some prefix parameter has been set to
RedisCacheMetadata
, but how exactly is this prefix used to form the key in Redis (e.g.,\xac\xed\x00\x05t\x00\tvc:501381 as you mentioned)?Basically, the
CacheInterceptor
will subsequently move forward to invoke a methodprivate RedisCacheKey getRedisCacheKey(Object key)
from the above-mentionedRedisCache
object, which returns an instance ofRedisCacheKey
by utilizing the prefix fromRedisCacheMetadata
and keySerializer fromRedisOperation
.By reaching this point, the "pre" advice of
CacheInterceptor
is completed, and it would go ahead to execute the actual method annotated by@Cacheable
. And after completing the execution of the actual method, it will do the "post" advice ofCacheInterceptor
, which essentially put the result to RedisCache. Below is the method of putting the result to redis cache:Within the
RedisCachePutCallback
object, its callback methoddoInRedis()
actually invoke a method to form the actual key in redis, and the method name isgetKeyBytes()
fromRedisCacheKey
instance. Below shows the details of this method:As we can see in the
getKeyBytes
method, it utilizes both the raw key (vc:501381 in your case) and prefix key (\xac\xed\x00\x05t\x00\t in your case).It's a very old question, but my answer might be helpful for someone who got the same issue while working with Redis using Spring Boot. I was stuck on the same issue while storing hash type data in redis. I have written the required config file changes for the RedisTemplate.
If the data type is String then
template.setHashValueSerializer(new StringRedisSerializer());
andtemplate.setHashKeySerializer(new StringRedisSerializer());
are not required.