fix(cache): exists 排除空值标记,与 get 口径一致
exists 原用 hasKey,会把持有空值标记的 key 判为"存在"(true),而 get 对同一 key 返回 null,二者口径打架。改为读值判断:空标记/缺失均返回 false,真实值返回 true。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -90,7 +90,9 @@ public class RedisCacheEnhanceTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean exists(String key) {
|
public boolean exists(String key) {
|
||||||
return Boolean.TRUE.equals(redis.hasKey(keyBuilder.build(key)));
|
// 与 get 口径一致:空值标记不算"存在"(物理 hasKey 会把空标记算存在,与 get→null 打架)
|
||||||
|
String raw = redis.opsForValue().get(keyBuilder.build(key));
|
||||||
|
return raw != null && !codec.isNullSentinel(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- 续期 ----
|
// ---- 续期 ----
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import java.util.function.Consumer;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
|
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
|
||||||
@@ -318,4 +319,24 @@ class RedisCacheEnhanceTemplateTest {
|
|||||||
void constructorAcceptsDefaults() {
|
void constructorAcceptsDefaults() {
|
||||||
new RedisCacheEnhanceTemplate(redis, keyBuilder, codec, new RedisCacheProperties());
|
new RedisCacheEnhanceTemplate(redis, keyBuilder, codec, new RedisCacheProperties());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- #7: exists 排除空值标记(与 get 口径一致) ----
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void existsTrueForRealValue() {
|
||||||
|
when(valueOps.get("cache:user:1")).thenReturn(JSON.toJSONString(new User(1L, "a")));
|
||||||
|
assertTrue(template.exists("user:1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void existsFalseForNullSentinel() {
|
||||||
|
when(valueOps.get("cache:user:1")).thenReturn(CacheConstant.NULL_SENTINEL);
|
||||||
|
assertFalse(template.exists("user:1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void existsFalseForMissing() {
|
||||||
|
when(valueOps.get("cache:user:1")).thenReturn(null);
|
||||||
|
assertFalse(template.exists("user:1"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user