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 ...
随机推荐
- CodeForces 459D Pashmak and Parmida's problem
Pashmak and Parmida's problem Time Limit:3000MS Memory Limit:262144KB 64bit IO Format:%I64d ...
- dropload.js下拉加载更多
项目中有用到下拉加载更多的地方,去网上找了一个插件,地址:http://ons.me/526.html总体还是不错的,可能自己不是特别了解这个插件,做项目时,也是遇到了无数问题.项目中要用的是两个ta ...
- 2014圣诞节一款纯css3实现的雪人动画特效
在2014年的圣诞节,爱编程小编给大家分分享一款纯css3实现的雪人动画特效.该实例实现一个雪人跳动的特效,效果图如下: 在线预览 源码下载 实现的代码. html代码: <span cla ...
- js监听 window.open 关闭事件
转载自:http://blog.csdn.net/hanshileiai/article/details/41346729 首先创建一个新的对象,这将打开一个弹出这样的: var winObj = w ...
- Oracle DBA面试突击题
一份ORACLE DBA面试题 一:SQL tuning 类 1:列举几种表连接方式 答: Oracle的多表连接算法有Nest Loop.Sort Merge和Hash Join三大类,每一类又可以 ...
- netctl
netctl is a CLI-based tool used to configure and manage network connections via profiles. It is a na ...
- 70个shell经常使用操作
1) 怎样向脚本传递參数 ? ./script argument 样例: 显示文件名脚本 ./show.sh file1.txt cat show.sh #!/bin/bash echo $1 2) ...
- C++ 匿名对象产生场景
//匿名对象产生的三种场景 #include<iostream> using namespace std; class Point{ public: Point(int a,int b){ ...
- 精心收集的Hadoop学习资料(持续更新)
转自:http://blog.csdn.net/wypblog/article/details/17528851 最近发现自己收集到的Hadoop学习资料有很多本,想想放在那里也浪费,所以觉得贴出来给 ...
- android sdk屏幕截图工具
调用android sdk中的工具,在开发板上截图. 使用usb线连接android设备,打开adb调试. 进入目录 sdk/tools/ 运行 traceview.bat 运行 uiautomato ...