diff --git a/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java b/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java index 42740e35c..cb6f669c7 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java +++ b/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java @@ -21,17 +21,8 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -253,7 +244,6 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean { return (R) accessor.getBean(); } - @SuppressWarnings("unchecked") @Nullable protected Object readProperty(String path, RedisData source, RedisPersistentProperty persistentProperty) { @@ -466,10 +456,9 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean { targetProperty = getTargetPropertyOrNullForPath(path.replaceAll("\\.\\[.*\\]", ""), update.getTarget()); TypeInformation ti = targetProperty == null ? ClassTypeInformation.OBJECT - : (targetProperty.isMap() - ? (targetProperty.getTypeInformation().getMapValueType() != null - ? targetProperty.getTypeInformation().getRequiredMapValueType() : ClassTypeInformation.OBJECT) - : targetProperty.getTypeInformation().getActualType()); + : (targetProperty.isMap() ? (targetProperty.getTypeInformation().getMapValueType() != null + ? targetProperty.getTypeInformation().getRequiredMapValueType() + : ClassTypeInformation.OBJECT) : targetProperty.getTypeInformation().getActualType()); writeInternal(entity.getKeySpace(), pUpdate.getPropertyPath(), pUpdate.getValue(), ti, sink); return; @@ -1055,11 +1044,11 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean { Object value = readProperty(path, source, property); - if (value != null && !property.getActualType().isInstance(value)) { - return (T) conversionService.convert(value, property.getActualType()); + if (value == null || ClassUtils.isAssignableValue(property.getType(), value)) { + return (T) value; } - return (T) value; + return (T) conversionService.convert(value, property.getType()); } } diff --git a/src/test/java/org/springframework/data/redis/core/convert/ConversionTestEntities.java b/src/test/java/org/springframework/data/redis/core/convert/ConversionTestEntities.java index 98b9e98b8..fb46a8eb3 100644 --- a/src/test/java/org/springframework/data/redis/core/convert/ConversionTestEntities.java +++ b/src/test/java/org/springframework/data/redis/core/convert/ConversionTestEntities.java @@ -15,6 +15,7 @@ */ package org.springframework.data.redis.core.convert; +import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -31,6 +32,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; import org.springframework.data.annotation.Id; @@ -213,4 +215,11 @@ public class ConversionTestEntities { Map decimalMapKeyMapping; Map dateMapKeyMapping; } + + @AllArgsConstructor + static class Device { + + final Instant now; + final Set profiles; + } } diff --git a/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java b/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java index 281daa8b6..69795fbb1 100644 --- a/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java +++ b/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java @@ -1472,6 +1472,18 @@ public class MappingRedisConverterUnitTests { assertThat(result.list.get(2), instanceOf(Date.class)); } + @Test // DATAREDIS-909 + public void shouldWriteReadObjectWithConstructorConversion() { + + Device sample = new Device(Instant.now(), Collections.singleton("foo")); + + RedisData rd = write(sample); + + Device result = converter.read(Device.class, rd); + assertThat(result.now, equalTo(sample.now)); + assertThat(result.profiles, equalTo(sample.profiles)); + } + @Test // DATAREDIS-509 public void writeHandlesArraysOfPrimitivesProperly() {