本文系原创,如有转载,请注明出处

在使用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写哈希表遇到的坑的更多相关文章

  1. [Codevs 1230]元素查找(手写哈希表)

    题目连接:http://codevs.cn/problem/1230/ 说白了就是要我们自己手写一个哈希表的数据结构来实现加入和查找功能.map也能直接过(我第一次写就是用map骗AC的) 提一下个人 ...

  2. PTA 7-42 整型关键字的散列映射(手写哈希表的线性探测法)

    本题考点: 整型哈希表的线性探测法 给定一系列整型关键字和素数P,用除留余数法定义的散列函数将关键字映射到长度为P的散列表中.用线性探测法解决冲突. 输入格式: 输入第一行首先给出两个正整数N(≤10 ...

  3. 哈希表的C实现(三)---传说中的暴雪版

    关于哈希表C实现,写了两篇学习笔记,不过似乎网上流传最具传奇色彩的莫过于暴雪公司的魔兽文件打包管理器里的hashTable的实现了:在冲突方面的处理方面,采用线性探测再散列.在添加和查找过程中进行了三 ...

  4. LeetCode通关:哈希表六连,这个还真有点简单

    精品刷题路线参考: https://github.com/youngyangyang04/leetcode-master https://github.com/chefyuan/algorithm-b ...

  5. 【哈希表】CodeVs1230元素查找

    一.写在前面 哈希表(Hash Table),又称散列表,是一种可以快速处理插入和查询操作的数据结构.哈希表体现着函数映射的思想,它将数据与其存储位置通过某种函数联系起来,其在查询时的高效性也体现在这 ...

  6. 漫谈Linux内核哈希表(1)

    关于哈希表,在内核里设计两个很重要的数据结构:    哈希链表节点: 点击(此处)折叠或打开 .x [include/linux/types.h]*/ struct hlist_node { stru ...

  7. noip模拟赛 好元素 哈希表的第一题

    这是一道关于 题2好元素 2s [问题描述] 小A一直认为,如果在一个由N个整数组成的数列{An}中,存在以下情况: Am+An+Ap = Ai (1 <= m, n, p < i < ...

  8. c# 哈希表跟函数

    一.哈希表集合 先进后出,一个一个赋值,但只能一起取值. 1.哈希表的建立.赋值以及读取. 2.利用枚举类型打印出集合中的Key值和Value值. 二.函数 函数:能够独立完成某项功能的模块. 函数四 ...

  9. Redis哈希表的实现要点

    Redis哈希表的实现要点 哈希算法的选择 针对不同的key使用不同的hash算法,如对整型.字符串以及大小写敏感的字符串分别使用不同的hash算法: 整型的Hash算法使用的是Thomas Wang ...

随机推荐

  1. java生成webservice

    使用Eclipse生成一个WebService应用 1.创建一个Dynamic web project 2.创建一个对外提供服务的类.比如: package com.guorui.services; ...

  2. sql server自定义函数

    CREATE function [dbo].[f_testFunc]( ) ,) ) ) as begin ); ); ); ); SELECT @str_id = a.id,@str_code = ...

  3. Linux快速定位并且杀掉占用端口的进程

    1.定位 lsof -i:8811(端口号) 2.杀掉进程 kill -9 63924

  4. alert的美化,并且随滚动条滚动

    onclick="sAlert('${vo.courseName}');" <script type="text/javascript" language ...

  5. kettle两表内链接的查询结果与sql语句的查询结果不符合?

    1.教师表输入 2.学生表 查 3.学生表中查出的教师id进行排序 5.教师表中查出的同样也对教师的id进行排序 6.进行左连接 总结: 进行连接的时候的关键是同样对教师的id进行先排序

  6. css -- hover伪类

    CSS代码: .btn-setDefaultGateway{display: none;} .netDiv:hover span .btn-setDefaultGateway { display: i ...

  7. 【BZOJ】1068: [SCOI2007]压缩(dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1068 发现如果只设一维的话无法转移 那么我们开第二维,发现对于前i个来说,如果确定了M在哪里,第i个 ...

  8. identity_insert---实验性插入大批量数据和分页存储过程

    OK,我们首先创建一数据库:data_Test,并在此数据库中创建一表:tb_TestTable 1create database data_Test --创建数据库data_Test 2use da ...

  9. 编程之美 set 21 24点游戏

    题目 输入: n1, n2, n3, n4 (1~13) 输出: 若能得到运算结果为 24, 则输出一个对应的运算表达式 如: 输入: 11, 8, 3, 5 输出: (11-8) * (3*5) = ...

  10. Spring.NET学习笔记——目录(原)

    目录 前言 Spring.NET学习笔记——前言 第一阶段:控制反转与依赖注入IoC&DI Spring.NET学习笔记1——控制反转(基础篇) Level 200 Spring.NET学习笔 ...