From cca1f7a8cfda8dc3827dc16981a444f00de5dfe1 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 6 Apr 2020 12:57:02 +0200 Subject: [PATCH] DATAREDIS-1106 - Remove expiration phantom key on delete via KeyValueAdapter. Original pull request: #521. --- .../data/redis/core/RedisKeyValueAdapter.java | 8 +++++- .../data/redis/core/TimeToLiveAccessor.java | 7 +++++ .../core/mapping/RedisMappingContext.java | 22 +++++++++++++--- .../core/mapping/RedisPersistentEntity.java | 7 +++++ .../redis/core/RedisKeyValueAdapterTests.java | 26 +++++++++++++++++++ 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java b/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java index 35478fc1a..a6b084b5f 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java +++ b/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java @@ -329,8 +329,14 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter connection.del(keyToDelete); connection.sRem(binKeyspace, binId); - new IndexWriter(connection, converter).removeKeyFromIndexes(asString(keyspace), binId); + + RedisPersistentEntity persistentEntity = converter.getMappingContext().getPersistentEntity(type); + if (persistentEntity != null && persistentEntity.isExpiring()) { + + byte[] phantomKey = ByteUtils.concat(keyToDelete, BinaryKeyspaceIdentifier.PHANTOM_SUFFIX); + connection.del(phantomKey); + } return null; }); } diff --git a/src/main/java/org/springframework/data/redis/core/TimeToLiveAccessor.java b/src/main/java/org/springframework/data/redis/core/TimeToLiveAccessor.java index 3bf240428..0241aa74a 100644 --- a/src/main/java/org/springframework/data/redis/core/TimeToLiveAccessor.java +++ b/src/main/java/org/springframework/data/redis/core/TimeToLiveAccessor.java @@ -31,4 +31,11 @@ public interface TimeToLiveAccessor { */ @Nullable Long getTimeToLive(Object source); + + /** + * @param type must not be {@literal null}. + * @return return {@literal true} if the entity could potentially expire. + * @since ? (depends on backport) + */ + boolean isExpiringEntity(Class type); } diff --git a/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java b/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java index 52c5c4f01..df34db1f1 100644 --- a/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java +++ b/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java @@ -206,10 +206,6 @@ public class RedisMappingContext extends KeyValueMappingContext type) { + + Long defaultTimeOut = resolveDefaultTimeOut(type); + + if (defaultTimeOut != null && defaultTimeOut > 0) { + return true; + } + if (resolveTtlProperty(type) != null) { + return true; + } + return resolveTimeMethod(type) != null; + } + private Long resolveDefaultTimeOut(Class type) { if (this.defaultTimeouts.containsKey(type)) { diff --git a/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java b/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java index 01063f6d3..eb43f2655 100644 --- a/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java +++ b/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java @@ -52,4 +52,11 @@ public interface RedisPersistentEntity extends KeyValuePersistentEntity