先上测试代码:
public class TestCache { private static final Cache testCache = Redis.use(CacheCons.TEST) ; public static void incrThenGet() { testCache.incr("ikey") ; testCache.get("ikey") ; } public static void setThenIncr() { testCache.set("ikey", 0) ; testCache.incr("ikey") ; } }
执行incrThenGet(),抛出错误:
java.lang.RuntimeException: java.io.IOException: java.lang.NullPointerException at com.jfinal.plugin.redis.serializer.FstSerializer.valueFromBytes(FstSerializer.java:84)
执行setThenIncr(),抛出错误:
redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of range at redis.clients.jedis.Protocol.processError(Protocol.java:127)
错误分析
incrThenGet()中,调用redis incr命令,当时ikey并不存在,redis会创建ikey,并将值初始化为0,然后执行incr加1操作,执行后的值为1.
get的时候,redis plugin默认redis中所有值都是java类型序列化之后的值,取到值后,会用FstSerializer这个类去反序列化。但是redis返回的值是字符1的ASCII值49,FstSerializer无法识别类型,因此抛出错误。
同理,在setThenIncr()中,redis plugin将ikey的值设为整型数值0,经过序列化后的二进制值为\xf7\x00,然后incr,redis只能对数值类型的值进行递增,\xf7\x00不认识,所以抛出错误。
redis hash类型的hincr也存在同样的问题。
这个问题如何解决呢?