Attempt early usage of custom converters.
We now try to eagerly apply a custom converter when reading Redis properties in the MappingRedisConverter before considering type hints from the hash. We require type hints to properly restore the target type for a hash entry as Redis data is all byte arrays, so a simple String needs a type hint before we can load it back into an e.g. Object-typed property. Subtypes of properties (such as ZoneRegion for ZoneId) are sometimes not associated with a converter as only the parent type (ZoneId) is associated with a converter. Trying to convert the value into the subtype directly through our ConversionService would fail in that case. Closes #2307
This commit is contained in:
@@ -319,6 +319,10 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (customConversions.hasCustomReadTarget(byte[].class, persistentProperty.getType())) {
|
||||
return fromBytes(sourceBytes, persistentProperty.getType());
|
||||
}
|
||||
|
||||
Class<?> typeToUse = getTypeHint(currentPath, source.getBucket(), persistentProperty.getType());
|
||||
return fromBytes(sourceBytes, typeToUse);
|
||||
}
|
||||
@@ -728,8 +732,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
* @param sink
|
||||
*/
|
||||
private void writeCollection(@Nullable String keyspace, String path, @Nullable Iterable<?> values,
|
||||
TypeInformation<?> typeHint,
|
||||
RedisData sink) {
|
||||
TypeInformation<?> typeHint, RedisData sink) {
|
||||
|
||||
if (values == null) {
|
||||
return;
|
||||
|
||||
@@ -696,11 +696,14 @@ class MappingRedisConverterUnitTests {
|
||||
assertThat(write(rand)).containsEntry("zoneId", "Europe/Paris");
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-425
|
||||
@Test // DATAREDIS-425, GH-2307
|
||||
void readsZoneIdValuesCorrectly() {
|
||||
|
||||
Person target = converter.read(Person.class,
|
||||
new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("zoneId", "Europe/Paris"))));
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("zoneId", "Europe/Paris");
|
||||
map.put("zoneId._class", "java.time.ZoneRegion");
|
||||
|
||||
Person target = converter.read(Person.class, new RedisData(Bucket.newBucketFromStringMap(map)));
|
||||
|
||||
assertThat(target.zoneId).isEqualTo(ZoneId.of("Europe/Paris"));
|
||||
}
|
||||
@@ -1790,7 +1793,6 @@ class MappingRedisConverterUnitTests {
|
||||
@Test // DATAREDIS-471
|
||||
void writeShouldThrowExceptionForUpdateValueInCollectionNotAssignableToDomainTypeProperty() {
|
||||
|
||||
|
||||
PartialUpdate<Person> update = new PartialUpdate<>("123", Person.class) //
|
||||
.set("coworkers", Collections.singletonList("foo"));
|
||||
|
||||
@@ -1928,7 +1930,7 @@ class MappingRedisConverterUnitTests {
|
||||
// FIXME: https://github.com/spring-projects/spring-data-redis/issues/2168
|
||||
void writePlainList() {
|
||||
|
||||
List<Object> source = Arrays.asList("Hello", "stream", "message", 100L);
|
||||
List<Object> source = Arrays.asList("Hello", "stream", "message", 100L);
|
||||
RedisTestData target = write(source);
|
||||
|
||||
assertThat(target).containsEntry("[0]", "Hello") //
|
||||
|
||||
Reference in New Issue
Block a user