redisTemplate写哈希表遇到的坑
本文系原创,如有转载,请注明出处
在使用spring的redisTemplate进行redis哈希表的相关操作时,遇到了下面比较奇怪的情况:
- 1.删掉哈希表所属的key之后,重新get这个key的值,得到的不是null,而是一个空的map
- 2.直接get一个不存在的key,得到的不是null,而是一个空的map
- 3.set进去一个null值值后,重新set一个非空的map,这个key对应的仍然是一个null
那先看一下我写的setHash和getHashTable这两个方法:
1.首先setHashTable
public void setHashTable(final String key, Map<String, String> value) {
Object res = redisTemplate.execute(new SessionCallback() {
@Override
public Object execute(RedisOperations operations) throws DataAccessException {
operations.multi();
operations.delete(generateKey(key));
operations.opsForHash().putAll(generateKey(key), value);
Object val = operations.exec();
return val;
}
});
if (res == null) {
log.error("redis transaction fail, key is : {}", key);
throw new RuntimeException("Redis transaction fail");
}
}
这个方法其实是对redisTemplate对哈希表set操作的封装(上面其实是用了事务操作)
2.getHashTable
public Map<String, String> getHashTable(final String key) {
try {
HashOperations<String, String, String> operations = redisTemplate.opsForHash();
Map<String, String> mapInRedis = operations.entries(generateKey(key));
return mapInRedis;
} catch (Exception e) {
log.warn("redis get Exception.", e);
}
return MapUtils.EMPTY_MAP;
}
好吧,针对遇到的问题,我追踪了一下redisTemplate的源码,debug进上面代码中黄色的地方看一下

我们可以看到,是调用的redisTemplate.execute方法。这个方法里面是对hGetAll的封装调用。
那我们看一下redis相关文档里面对HGETALL的解释:http://redisdoc.com/hash/hgetall.html

我们自己在终端实验一下:

果然哈,输入一个不存在的key,返回的不是null,而是一个empty list or set
那么程序里面返回的是{}就可以理解了。
接下来查后面set进null值的问题。我们上述代码中调用的是putAll方法:

看源码可以发现,这个方法写着,m 不可以为空。如果是null有什么后果呢

这个方法里面已经假定m不为null了,直接判断是否为空的empty。那么其实如果m是null,是不会走进这个方法里面来的,至少m.isEmpty这里会报NPE。
还没有周到具体的原因。那我猜应该是传入null的时候,报了空指针,某个地方拦截住然后把这个key锁住了
redisTemplate写哈希表遇到的坑的更多相关文章
- [Codevs 1230]元素查找(手写哈希表)
题目连接:http://codevs.cn/problem/1230/ 说白了就是要我们自己手写一个哈希表的数据结构来实现加入和查找功能.map也能直接过(我第一次写就是用map骗AC的) 提一下个人 ...
- PTA 7-42 整型关键字的散列映射(手写哈希表的线性探测法)
本题考点: 整型哈希表的线性探测法 给定一系列整型关键字和素数P,用除留余数法定义的散列函数将关键字映射到长度为P的散列表中.用线性探测法解决冲突. 输入格式: 输入第一行首先给出两个正整数N(≤10 ...
- 哈希表的C实现(三)---传说中的暴雪版
关于哈希表C实现,写了两篇学习笔记,不过似乎网上流传最具传奇色彩的莫过于暴雪公司的魔兽文件打包管理器里的hashTable的实现了:在冲突方面的处理方面,采用线性探测再散列.在添加和查找过程中进行了三 ...
- LeetCode通关:哈希表六连,这个还真有点简单
精品刷题路线参考: https://github.com/youngyangyang04/leetcode-master https://github.com/chefyuan/algorithm-b ...
- 【哈希表】CodeVs1230元素查找
一.写在前面 哈希表(Hash Table),又称散列表,是一种可以快速处理插入和查询操作的数据结构.哈希表体现着函数映射的思想,它将数据与其存储位置通过某种函数联系起来,其在查询时的高效性也体现在这 ...
- 漫谈Linux内核哈希表(1)
关于哈希表,在内核里设计两个很重要的数据结构: 哈希链表节点: 点击(此处)折叠或打开 .x [include/linux/types.h]*/ struct hlist_node { stru ...
- noip模拟赛 好元素 哈希表的第一题
这是一道关于 题2好元素 2s [问题描述] 小A一直认为,如果在一个由N个整数组成的数列{An}中,存在以下情况: Am+An+Ap = Ai (1 <= m, n, p < i < ...
- c# 哈希表跟函数
一.哈希表集合 先进后出,一个一个赋值,但只能一起取值. 1.哈希表的建立.赋值以及读取. 2.利用枚举类型打印出集合中的Key值和Value值. 二.函数 函数:能够独立完成某项功能的模块. 函数四 ...
- Redis哈希表的实现要点
Redis哈希表的实现要点 哈希算法的选择 针对不同的key使用不同的hash算法,如对整型.字符串以及大小写敏感的字符串分别使用不同的hash算法: 整型的Hash算法使用的是Thomas Wang ...
随机推荐
- 方程式漏洞之复现window2008/win7 远程命令执行漏洞
前几天就想写的,因为一些缘故就没写.此次是在外网环境下进行的.大家在内网中也一个样. 方法: 使用Eternalblue模块,剑测是否有漏洞然后msf生成一个dll直接反弹shell. PS:win版 ...
- boa 服务的启动
使用 buildroot 添加 boa 服务后,通过命令 boa 不能启动该服务,就研究了一下boa.conf的配置. etc/boa/boa.conf # 更改user 和Group 为root. ...
- 用SVN checkout源码时,设置账号
如果直接在“svn co”后加url的话,svn老是要我登录操作系统用户名对应的密码. Ubuntu系统 ================== 用“svn co --help”命令看到如下的选项 Gl ...
- keepalive的作用
keepalive的作用是实现高可用,通过VIP虚拟IP的漂移实现高可用.在相同集群内发送组播包,master主通过VRRP协议发送组播包,告诉从主的状态. 一旦主挂了从就选举新的主,实现高可用 LV ...
- Toad 补充与培训 & 常用菜单
Toad 常用菜单 新版本 toad 软件中, 比较有用的菜单 (toad10.6 版本) 下边菜单, 在日常工作中出现过的, 显示为 粉色 , 蓝色 表示次一级的重要 session 菜单 new ...
- SQL Server 2012附加数据库报错
操作系统: win8 数据库:SQL 2012 遇到问题: 以管理员身份登录SQL 2012,附件数据库提示如下错误: 解决办法: 以windows账号登录,附加,成功!
- ubuntu 按键替换 Control_R to Left
ubuntu 按键替换 Control_R to Left 1 查看当前键盘布局 $xmodmap -pke keycode 105 = Control_R NoSymbol Control_Rkey ...
- 第二百六十八节,Tornado框架-路由映射之二级域名支持,html模板继承以及导入
Tornado框架-路由映射之二级域名支持,html模板继承以及导入 二级域名路由映射add_handlers()设置二级域名路由映射 注意:二级域名需要结合服务器ip绑定域名 框架引擎 #!/usr ...
- c#并行扫描端口控制台程序
static void Main(string[] args) { Console.WriteLine("请输入ip"); string ip = Console.ReadLine ...
- 深入分析jquery解析json数据
我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法. JSON数据如下,是一个嵌套JSON: {"comments":[{& ...