Record使用Jackson反序列化报错

项目中新定义ICache,使用redis(使用Jackson序列化)进行数据缓存,然后调用查询,代码如下:

Record findFirstByCache(String cacheName, Object key, String sql, Object... paras)

发现第一次查询可以正常缓存数据,但是第二次查询即报错(Jackson反序列化报错),大概知道是Record的columns属性存在多个set方法导致,但是未想到解决办法,错误信息如下:

Conflicting setter definitions for property "columns": com.jfinal.plugin.activerecord.Record#setColumns(1 params) vs com.jfinal.plugin.activerecord.Record#setColumns(1 params)




评论区

杜福忠

2021-12-08 17:25

要不,细说说 “使用Jackson序列化” 这个地方? 贴点代码什么的,是自定义implements ISerializer 吗?

袁小猴

2021-12-08 19:27

@杜福忠 序列化用的是redis自带的Jackson2JsonRedisSerializer,虽然我使用JdkSerializationRedisSerializer序列化可以规避这个问题,但是这是不是意味着Record对象的设计对于想要使用Jackson序列化处理,兼容的不是特别友好,打个问号???

杜福忠

2021-12-09 10:02

@袁小猴 我明白了,你的逻辑是这样的:
findFirstByCache 》数据库查询 并 set 缓存
ICache》自定义
Jackson》转json字符串
Redis》Jedis对象set字符串存储
二次查询时:
findFirstByCache 》数据库查询 并 get 缓存
ICache》自定义
Redis》Jedis对象get字符串
Jackson》json字符串转Record

原因是Record不是传统javaBean也不是Map,那处理就比较简单了,
1是先字符串转成对象之后再转Record即可。
2是Record支持这些JSON工具set值即可。
稍后我写个demo

杜福忠

2021-12-09 18:37

如果是我说的这个逻辑,
那么可以自建一个MyDbPro
https://jfinal.com/share/2399
然后覆写里面的findFirstByCache系列方法,
里面代码返回时转调一下这个方法就可以:
public static <T>T toRecord(Object parse){
if (parse instanceof Map){
Record record = new Record();
com.jfinal.plugin.activerecord.CPI.setColumnsMap(record, (Map)parse);
return (T) record;
}else if (parse instanceof List){
List array = (List) parse;
for (int i = 0; i < array.size(); i++) {
array.set(i, toRecord(array.get(i)));
}
return (T) array;
}
return (T) parse;
}
如果不是为了跨语言编写项目,感觉用Jackson序列化不划算了。
这里再说一下,String s = JFinalJson.getJson().toJson(record);
toJson时一定要用JFinalJson

袁小猴

2021-12-23 10:21

@杜福忠 哈哈哈,看到晚了,万分感谢~