3

Tested with jedis 2.6.1 and 2.6.2.

redisTemplate.opsForHash().put("mykey", "myhashkey", 1);

127.0.0.1:6379> hkeys "mykey"
1) "\xac\xed\x00\x05t\x00\tmyhashkey"

127.0.0.1:6379> hget "mykey" "\xac\xed\x00\x05t\x00\tmyhashkey"
"\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01"

Then I'm trying to increment my value

redisTemplate.opsForHash().increment("mykey", "myhashkey", 1);

but I got the following problem:

org.springframework.dao.InvalidDataAccessApiUsageException: ERR hash value is not an integer; nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR hash value is not an integer

When I'm doing

redisTemplate.opsForHash().increment("mykey", "myhashkey1", 1);

and field is not present in redis than it works perfect.

Any advice?

Alex
  • 967
  • 4
  • 15
  • 38
  • So have you tried the raw `hset` as in my answer ? I have found a way to disable serialization, with `redisTemplate.enableDefaultSerializer = false;`, but that is not a decent solution nevertheless. – Niloct Mar 05 '15 at 13:23
  • @Niloct no, i didn't tried yet. but i agree with you that the problem is serialisation. – Alex Mar 05 '15 at 13:27

3 Answers3

1

After you do redisTemplate.opsForHash().put("mykey", "myhashkey", 1); from hget result you can see that you result is serial by default JDK serializer. If you want to save hash as your origin value you should use StringRedisSerializer as serial method.

For example you should configure redisTemplate part in xml as follow:

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="keySerializer">
    <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
</property>
<property name="hashKeySerializer">
    <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashValueSerializer">
    <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>

Then if you do redisTemplate.opsForHash().put("mykey", "myhashkey", 1), and then do redisTemplate.opsForHash().increment("mykey", "myhashkey1", 1);, it works. Because using StringRedisSerializer, it saves 1 into "1", and default JDK Serializer would save 1 to serial such as "\xac\xed\x00\x0".

Fujian lin
  • 101
  • 1
  • 3
0

Well the answer is in your post!

hget "mykey" "\xac\xed\x00\x05t\x00\tmyhashkey"

The value stored in your hash's key \xac\xed\x00\x05t\x00\tmyhashkey is not an integer, it's

"\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01"

(it seems a serialization of a java object).

If you hset mykey \xac\xed\x00\x05t\x00\tmyhashkey 1, and then you issue an increment, it should work.

I still have to study how your client works, I've only dealed with PHPRedis which is awesome. Let's see what I can find.

Niloct
  • 9,491
  • 3
  • 44
  • 57
0

set hash key and value serializer like this:

redisTemplate.setHashKeySerializer(new StringRedisSerializer(StandardCharsets.UTF_8));
redisTemplate.setHashValueSerializer(new StringRedisSerializer(StandardCharsets.UTF_8));

and put value like this:

redisTemplate.opsForHash().increment("mykey", "myhashkey", "1");
Persia
  • 855
  • 5
  • 8