Why is data getting stored with weird keys in Redis when using Jedis with Spring Data?

arun picture arun · Nov 4, 2012 · Viewed 38.3k times · Source

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?

Answer

arun picture arun · Nov 4, 2012

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:

<bean 
    id="jedisConnectionFactory" 
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
    p:host-name="${redis.server}" 
    p:port="${redis.port}" 
    p:use-pool="true"/>

<bean 
    id="stringRedisSerializer" 
    class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

<bean 
    id="redisTemplate" 
    class="org.springframework.data.redis.core.RedisTemplate"
    p:connection-factory-ref="jedisConnectionFactory" 
    p:keySerializer-ref="stringRedisSerializer"
    p:hashKeySerializer-ref="stringRedisSerializer" 
/>

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:

<bean 
    id="redisTemplate" 
    class="org.springframework.data.redis.core.RedisTemplate"
    p:connection-factory-ref="jedisConnectionFactory" 
    p:defaultSerializer-ref="stringRedisSerializer"
/>

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:

<bean id="userJsonRedisSerializer" class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer">
    <constructor-arg type="java.lang.Class" value="com.mycompany.redis.domain.User"/>
</bean>

and configure your template as:

<bean 
    id="redisTemplate" 
    class="org.springframework.data.redis.core.RedisTemplate"
    p:connection-factory-ref="jedisConnectionFactory" 
    p:keySerializer-ref="stringRedisSerializer"
    p:hashKeySerializer-ref="stringRedisSerializer" 
    p:valueSerialier-ref="userJsonRedisSerializer"
/>