本文系原創,若有轉載,請註明出處 html
在使用spring的redisTemplate進行redis哈希表的相關操做時,遇到了下面比較奇怪的狀況:redis
那先看一下我寫的setHash和getHashTable這兩個方法:spring
1.首先setHashTableide
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操做的封裝(上面實際上是用了事務操做)spa
2.getHashTabledebug
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的封裝調用。code
那咱們看一下redis相關文檔裏面對HGETALL的解釋:http://redisdoc.com/hash/hgetall.htmlhtm
咱們本身在終端實驗一下:blog
果真哈,輸入一個不存在的key,返回的不是null,而是一個empty list or set
那麼程序裏面返回的是{}就能夠理解了。
接下來查後面set進null值的問題。咱們上述代碼中調用的是putAll方法:
看源碼能夠發現,這個方法寫着,m 不能夠爲空。若是是null有什麼後果呢
這個方法裏面已經假定m不爲null了,直接判斷是否爲空的empty。那麼其實若是m是null,是不會走進這個方法裏面來的,至少m.isEmpty這裏會報NPE。
尚未周到具體的緣由。那我猜應該是傳入null的時候,報了空指針,某個地方攔截住而後把這個key鎖住了