diff --git a/src/main/java/io/lettuce/core/dynamic/codec/AnnotationRedisCodecResolver.java b/src/main/java/io/lettuce/core/dynamic/codec/AnnotationRedisCodecResolver.java index ebb1ee5d17..5fa2a549b0 100644 --- a/src/main/java/io/lettuce/core/dynamic/codec/AnnotationRedisCodecResolver.java +++ b/src/main/java/io/lettuce/core/dynamic/codec/AnnotationRedisCodecResolver.java @@ -33,9 +33,9 @@ * determine a {@link RedisCodec} that is able to handle all involved types. * * @author Mark Paluch - * @since 5.0 * @see Key * @see Value + * @since 5.0 */ public class AnnotationRedisCodecResolver implements RedisCodecResolver { @@ -71,18 +71,23 @@ public AnnotationRedisCodecResolver(List> codecs) { return codecs.get(0); } - if ((keyTypes.size() == 1 && (valueTypes.isEmpty() || valueTypes.size() == 1)) - || (valueTypes.size() == 1 && (keyTypes.isEmpty() || keyTypes.size() == 1))) { - - RedisCodec codec = resolveCodec(keyTypes, valueTypes); - if (codec != null) { - return codec; + if (methodHasAtMostOneCodec(keyTypes, valueTypes)) { + RedisCodec resolvedCodec = resolveCodec(keyTypes, valueTypes); + if (resolvedCodec != null) { + return resolvedCodec; } } throw new IllegalStateException(String.format("Cannot resolve Codec for method %s", commandMethod.getMethod())); } + private boolean methodHasAtMostOneCodec(Set> keyTypes, Set> valueTypes) { + final int keyTypesSize = keyTypes.size(); + final int valueTypesSize = valueTypes.size(); + + return keyTypesSize == 1 && valueTypesSize <= 1 || valueTypesSize == 1 && keyTypesSize <= 1; + } + private Voted> voteForTypeMajority(CommandMethod commandMethod) { List>> votes = codecs.stream().map(redisCodec -> new Voted>(redisCodec, 0)) @@ -139,12 +144,10 @@ private static void vote(List>> votes, Parameter paramete } private RedisCodec resolveCodec(Set> keyTypes, Set> valueTypes) { - Class keyType = keyTypes.isEmpty() ? null : keyTypes.iterator().next(); Class valueType = valueTypes.isEmpty() ? null : valueTypes.iterator().next(); for (RedisCodec codec : codecs) { - ClassTypeInformation typeInformation = ClassTypeInformation.from(codec.getClass()); TypeInformation keyTypeArgument = typeInformation.getTypeArgument(RedisCodec.class, 0); TypeInformation valueTypeArgument = typeInformation.getTypeArgument(RedisCodec.class, 1); diff --git a/src/test/java/io/lettuce/core/dynamic/codec/AnnotationRedisCodecResolverUnitTests.java b/src/test/java/io/lettuce/core/dynamic/codec/AnnotationRedisCodecResolverUnitTests.java index 35f399c8ed..ffe51f61d0 100644 --- a/src/test/java/io/lettuce/core/dynamic/codec/AnnotationRedisCodecResolverUnitTests.java +++ b/src/test/java/io/lettuce/core/dynamic/codec/AnnotationRedisCodecResolverUnitTests.java @@ -89,12 +89,17 @@ void shouldResolveHintedByteArrayValue() { } @Test - void resolutionShouldFail() { - + void resolutionOfMethodWithMixedTypesShouldFail() { Method method = ReflectionUtils.findMethod(CommandMethods.class, "mixedTypes", String.class, byte[].class); assertThatThrownBy(() -> resolve(method)).isInstanceOf(IllegalStateException. class); } + @Test + void resolutionOfMethodWithMixedCodecsShouldFail() { + Method method = ReflectionUtils.findMethod(CommandMethods.class, "mixedCodecs", String.class, byte[].class, String.class); + assertThatThrownBy(() -> resolve(method)).isInstanceOf(IllegalStateException. class); + } + @Test void shouldDiscoverCodecTypesFromWrappers() { @@ -129,6 +134,8 @@ private static interface CommandMethods { String mixedTypes(@Key String key, @Value byte[] value); + String mixedCodecs(@Key String key1, @Key byte[] key2, @Value String value); + String withWrappers(@Value Range range, @Value io.lettuce.core.Value value); String withMap(Map map);