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锁住了

原文地址:https://www.cnblogs.com/sonofelice/p/9026477.html

时间: 2024-10-18 06:49:22

redisTemplate写哈希表遇到的坑的相关文章

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

题目连接:http://codevs.cn/problem/1230/ 说白了就是要我们自己手写一个哈希表的数据结构来实现添加和查找功能,map也能直接过(我第一次写就是用map骗AC的) 提一下个人理解的哈希表的实现(下面说的是线性寻址法),如果有误还请各位大神不吝指教 用一个数组模拟哈希表,函数f(x)=数字x在哈希表中出现的下标的最小可能值,一般f(x)=x mod t,t就是哈希表的长度 下面就是一个哈希表的示例,如果遍历哈希表时指针走出了哈希表的终点,就进入起点重新遍历 对于每次向哈希

看数据结构写代码(61) 哈希表

前面说的 各种查找都是 基于 "比较" 的基础 来进行 查找的.查找的 效率 要 看 比较的 次数.那么 有没有 不需要 比较,就可以 找到 想要的数据的 方法呢? 哈希表 就是 这样的 一种方法,它用  数组 作为 保存 关键字的 数据原型,通过 一个 哈希 函数f(k),来找到 关键字 存储的位置,从而 找到想要的信息. 例如 我们 想要解决 这样的一个问题: 假设这有一个各种字母组成的字符串,假设这还有另外一个字符串,而且这个字符串里的字母数相对少一些.什么方法能最快的查出所有小

哈希表之一初步原理了解

考虑如下场景:小明住在芳华小区,芳华小区中有很多幢房子,每个房子有十几二十层,每层有4个住户: 现在小红要去找小明玩耍,现在假设小红只知道小明住在芳华小区,但是不知道住在哪一幢,哪一层和哪一户,]. 那么小红要怎么才能找到小明呢? 那么毫无疑问,小红只有在芳华小区中一家一家地敲门问小明住在哪儿? (此时不允许小红叫一个收破烂的拿着喇叭在楼下喊:"小明,额想你!") 这个时候,如果小红有芳华小区的所有住户的明细的话,就可以从明细上找到小明住的地方,然后根据这个地方在芳华小区中找到小明,

SDUTOJ Crack Mathmen(模拟,哈希表,快速幂)

题目连接:传送门 这一题是我们昨天省赛集训的题目,我可给坑惨了.不过所幸没有给白坑,学到了一些东西.最有感触的是这个 for(int i = 0 ; i < strlen(str); i++) //危险,切勿模仿 如果数组大一些,这样写就直接超时.我之前找了好久都没发现,最后学长告诉我把他写成这样 int len = strlen(str); for(int i = 0 ; i < len; i++) 为什么呢?原因是如果数组较大的话,那么就要计算 strlen(str)次的str的长度,这样

哈希表线性探测

HashTable-散列表/哈希表,是根据关键字(key)而直接访问在内存存储位置的数据结构. 它通过一个关键值的函数将所需的数据映射到表中的位置来访问数据,这个映射函数叫做散列函数,存放记录的数组叫做散列表. 哈希冲突/哈希碰撞 不同的Key值经过哈希函数Hash(Key)处理以后可能产生相同的值哈希地址,我们称这种情况为哈希冲突.任意的散列函数都不能避免产生冲突. 我给大家介绍的是哈希表的线性探测,线性探测的基本思路: 1.用一个数据除以散列表的长度,余数是多少,就把这个数放在散列表下标相同

Code Review:C#与JAVA的哈希表内部机制的一些区别

看C#与JAVA源码时发现C#与JAVA哈希表的实现略有不同,特此分享一下. 我觉得看哈希表的机制可以从"碰撞"这里划线分为两部分来分析. 1,发生碰撞前 在发生碰撞前决定get与put的速度唯一因素是通过哈希函数计算键值位置的速度.而占用空间大小取决于需要的桶的数量(取决于极限装载值(load factor)(假设已知需要放入哈希表中元素的数量)),和桶的大小. C#的默认装载系数=0.72 // Based on perf work, .72 is the optimal load

哈希表入门讲解

散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构.也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度.这个映射函数称做散列函数,存放记录的数组称做散列表. 一个通俗的例子是,为了查找电话簿中某人的号码,可以创建一个按照人名首字母顺序排列的表(即建立人名{\displaystyle x}到首字母{\displaystyle F(x)}的一个函数关系),在首字母为W的表中查找"王"姓的电话号

上古时代 Objective-C 中哈希表的实现

因为 ObjC 的 runtime 只能在 Mac OS 下才能编译,所以文章中的代码都是在 Mac OS,也就是 x86_64 架构下运行的,对于在 arm64 中运行的代码会特别说明. 写在前面 文章会介绍上古时代 Objective-C 哈希表,也就是 NXHashTable : NXHashTable 的实现 NXHashTable 的性能分析 NXHashTable 的作用 NXHashTable 的实现有着将近 30 年的历史,不过仍然作为重要的底层数据结构存储整个应用中的类. 文中

数据结构之哈希表--预习篇

数据结构实验:哈希表 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 在n个数中,找出出现次数最多那个数字,并且输出出现的次数.如果有多个结果,输出数字最小的那一个. 输入 单组数据,第一行数字n(1<=n<=100000). 接下来有n个数字,每个数字不超过100000000 输出 出现次数最多的数字和次数. 示例输入 3 1 1 2 示例输出 1 2 首先声明本渣还没学会哈希,这篇就当哈希的预习篇吧 写的不好大家见谅 首