From 9a56c38e2c99fa7e7c811694fb366d1e26663ac2 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 10 Dec 2021 09:54:19 +0100 Subject: [PATCH] =?UTF-8?q?Return=20single-element=20list=20with=20empty?= =?UTF-8?q?=20value=20when=20ReactiveHashOperations.hMGet(=E2=80=A6)=20for?= =?UTF-8?q?=20a=20single=20key=20returns=20no=20value.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now return a list containing a single empty KeyValue element when ReactiveHashOperations.hMGet(…) called for a single key returns no value. Previously, the code used onErrorReturn(…) which returned the wrong value and suppressed errors. Closes #2210 --- .../data/redis/connection/ReactiveHashCommands.java | 3 ++- .../lettuce/LettuceReactiveHashCommands.java | 2 +- .../LettuceReactiveHashCommandsIntegrationTests.java | 10 +++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveHashCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveHashCommands.java index 765634017..e7ad7c042 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveHashCommands.java @@ -283,7 +283,8 @@ public interface ReactiveHashCommands { * @see Redis Documentation: HGET */ default Mono hGet(ByteBuffer key, ByteBuffer field) { - return hMGet(key, Collections.singletonList(field)).flatMapIterable(Function.identity()).next(); + return hMGet(key, Collections.singletonList(field)).filter(it -> !it.contains(null)) + .flatMapIterable(Function.identity()).next(); } /** diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveHashCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveHashCommands.java index b1103de1e..10d2a77bf 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveHashCommands.java @@ -107,7 +107,7 @@ class LettuceReactiveHashCommands implements ReactiveHashCommands { if (command.getFields().size() == 1) { ByteBuffer key = command.getFields().iterator().next(); result = cmd.hget(command.getKey(), key.duplicate()).map(value -> KeyValue.fromNullable(key, value)) - .map(Collections::singletonList).onErrorReturn(Collections.emptyList()); + .defaultIfEmpty(KeyValue.empty(key)).map(Collections::singletonList); } else { result = cmd.hmget(command.getKey(), command.getFields().stream().toArray(ByteBuffer[]::new)).collectList(); } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveHashCommandsIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveHashCommandsIntegrationTests.java index a1dacc10b..d14afac52 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveHashCommandsIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveHashCommandsIntegrationTests.java @@ -22,6 +22,7 @@ import reactor.test.StepVerifier; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -110,12 +111,19 @@ public class LettuceReactiveHashCommandsIntegrationTests extends LettuceReactive }).verifyComplete(); } - @ParameterizedRedisTest // DATAREDIS-525 + @ParameterizedRedisTest // DATAREDIS-525, GH-2210 void hMGetShouldReturnNullValueForFieldsThatHaveNoValue() { nativeCommands.hset(KEY_1, FIELD_1, VALUE_1); nativeCommands.hset(KEY_1, FIELD_3, VALUE_3); + connection.hashCommands().hMGet(KEY_1_BBUFFER, Collections.singletonList(FIELD_1_BBUFFER)).as(StepVerifier::create) + .expectNext(Collections.singletonList(VALUE_1_BBUFFER)).verifyComplete(); + + connection.hashCommands().hMGet(KEY_1_BBUFFER, Collections.singletonList(FIELD_2_BBUFFER)) + .as(StepVerifier::create) + .expectNext(Collections.singletonList(null)).verifyComplete(); + connection.hashCommands().hMGet(KEY_1_BBUFFER, Arrays.asList(FIELD_1_BBUFFER, FIELD_2_BBUFFER, FIELD_3_BBUFFER)) .as(StepVerifier::create) .expectNext(Arrays.asList(VALUE_1_BBUFFER, null, VALUE_3_BBUFFER)).verifyComplete();