Monday, July 11, 2016

Spring framework - Strange characters in Spring writing key to redis

Strange characters in Spring writing key to redis

With the redisTemplate bean declared, Spring is ready to manipulate data on redis

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

But after the key is set from Spring, you will see the addition strange characters like to “\xac\xed\x00\x05t\x00\t” prepended to the key on redis

redis> keys *
"\xac\xed\x00\x05t\x00\takey"

To get rid of that, create a redis serializer bean

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

and inject it to keySerializer in redisTemplate.

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

so that the key will not have the unwanted characters.

The values still have them

Without configuring value serializer, the extra characters may not affect the output of reading values. But it will cause “redis.clients.jedis.exceptions.JedisDataException: ERR hash value is not an integer” if you try to do HashOperations.increment(H key, HK hashKey, long delta). That’s because the value is not a number and the operation tries to increment the number before deserialization. In order to for increment() work properly, it’s necessary to inject the redis serializer with Long class to valueSerializer in redis template

<bean id="longRedisSerializer" class="org.springframework.data.redis.serializer.GenericToStringSerializer">
    <constructor-arg type="java.lang.Class" value="java.lang.Long"/>
</bean>

for Sets

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

for Hashes

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

References

  1. Weird redis key with spring data Jedis
  2. spring-data-redis redisTemplate Excetion