DATAREDIS-768 - Consider map key type in MappingRedisConverter.readMap…(…).
We now consider the key type when reading a map from a Redis Hash. Previously, map keys were read as string while a map could declare numeric keys. Original Pull Request: #312
This commit is contained in:
committed by
Christoph Strobl
parent
d6d5b9e610
commit
208f9e12c4
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core.convert;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
@@ -844,9 +844,14 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Cannot extract map value for key '%s' in path '%s'.", entry.getKey(), path));
|
||||
}
|
||||
String key = matcher.group(2);
|
||||
Object key = matcher.group(2);
|
||||
|
||||
Class<?> typeToUse = getTypeHint(path + ".[" + key + "]", source.getBucket(), valueType);
|
||||
|
||||
if (!keyType.isAssignableFrom(key.getClass())) {
|
||||
key = conversionService.convert(key, keyType);
|
||||
}
|
||||
|
||||
target.put(key, fromBytes(entry.getValue(), typeToUse));
|
||||
}
|
||||
|
||||
@@ -879,7 +884,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Cannot extract map value for key '%s' in path '%s'.", key, path));
|
||||
}
|
||||
String mapKey = matcher.group(2);
|
||||
Object mapKey = matcher.group(2);
|
||||
|
||||
Bucket partial = source.getBucket().extract(key);
|
||||
|
||||
@@ -888,8 +893,13 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
partial.put(TYPE_HINT_ALIAS, typeInfo);
|
||||
}
|
||||
|
||||
Object o = readInternal(key, valueType, new RedisData(partial));
|
||||
target.put(mapKey, o);
|
||||
if (!keyType.isAssignableFrom(mapKey.getClass())) {
|
||||
mapKey = conversionService.convert(mapKey, keyType);
|
||||
}
|
||||
|
||||
Object value = readInternal(key, valueType, new RedisData(partial));
|
||||
|
||||
target.put(mapKey, value);
|
||||
}
|
||||
|
||||
return target.isEmpty() ? null : target;
|
||||
|
||||
@@ -57,6 +57,7 @@ public class ConversionTestEntities {
|
||||
|
||||
List<String> nicknames;
|
||||
List<Person> coworkers;
|
||||
List<Integer> positions;
|
||||
Integer age;
|
||||
Boolean alive;
|
||||
Date birthdate;
|
||||
@@ -73,7 +74,9 @@ public class ConversionTestEntities {
|
||||
Address address;
|
||||
|
||||
Map<String, String> physicalAttributes;
|
||||
Map<Integer, Integer> numberMapping;
|
||||
Map<String, Person> relatives;
|
||||
Map<Integer, Person> favoredRelatives;
|
||||
|
||||
@Reference Location location;
|
||||
@Reference List<Location> visited;
|
||||
|
||||
@@ -275,6 +275,18 @@ public class MappingRedisConverterUnitTests {
|
||||
assertThat(converter.read(Person.class, rdo).nicknames, contains("dragon reborn", "car'a'carn", "lews therin"));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-768
|
||||
public void readConvertsUnorderedListOfSimpleIntegerPropertiesCorrectly() {
|
||||
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
map.put("positions.[9]", "0");
|
||||
map.put("positions.[10]", "1");
|
||||
map.put("positions.[1]", "2");
|
||||
RedisData rdo = new RedisData(Bucket.newBucketFromStringMap(map));
|
||||
|
||||
assertThat(converter.read(Person.class, rdo).positions, contains(2, 0, 1));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-425
|
||||
public void readComplexPropertyCorrectly() {
|
||||
|
||||
@@ -402,6 +414,22 @@ public class MappingRedisConverterUnitTests {
|
||||
assertThat(target.physicalAttributes.get("eye-color"), is("grey"));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-768
|
||||
public void readSimpleIntegerMapValuesCorrectly() {
|
||||
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
map.put("numberMapping.[1]", "2");
|
||||
map.put("numberMapping.[3]", "4");
|
||||
|
||||
RedisData rdo = new RedisData(Bucket.newBucketFromStringMap(map));
|
||||
|
||||
Person target = converter.read(Person.class, rdo);
|
||||
|
||||
assertThat(target.numberMapping, notNullValue());
|
||||
assertThat(target.numberMapping.get(1), is(2));
|
||||
assertThat(target.numberMapping.get(3), is(4));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-425
|
||||
public void writeAppendsMapWithComplexObjectsCorrectly() {
|
||||
|
||||
@@ -437,6 +465,22 @@ public class MappingRedisConverterUnitTests {
|
||||
assertThat(target.relatives.get("step-father").firstname, is("tam"));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-768
|
||||
public void readMapWithIntegerKeysAndComplexObjectsCorrectly() {
|
||||
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
map.put("favoredRelatives.[1].firstname", "janduin");
|
||||
map.put("favoredRelatives.[2].firstname", "tam");
|
||||
|
||||
Person target = converter.read(Person.class, new RedisData(Bucket.newBucketFromStringMap(map)));
|
||||
|
||||
assertThat(target.favoredRelatives, notNullValue());
|
||||
assertThat(target.favoredRelatives.get(1), notNullValue());
|
||||
assertThat(target.favoredRelatives.get(1).firstname, is("janduin"));
|
||||
assertThat(target.favoredRelatives.get(2), notNullValue());
|
||||
assertThat(target.favoredRelatives.get(2).firstname, is("tam"));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-425
|
||||
public void writeAppendsClassTypeInformationCorrectlyForMapWithComplexObjects() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user