Skip to content

Commit 2492fbe

Browse files
gregturnchristophstrobl
authored andcommitted
DATAREDIS-492 - Handle serializing arrays and collections.
Original Pull Request: #189
1 parent deec98e commit 2492fbe

File tree

3 files changed

+95
-8
lines changed

3 files changed

+95
-8
lines changed

src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.springframework.data.redis.core.convert;
1717

1818
import java.util.ArrayList;
19+
import java.util.Arrays;
1920
import java.util.Collection;
2021
import java.util.Collections;
2122
import java.util.Comparator;
@@ -100,6 +101,7 @@
100101
* </pre>
101102
*
102103
* @author Christoph Strobl
104+
* @author Greg Turnquist
103105
* @since 1.7
104106
*/
105107
public class MappingRedisConverter implements RedisConverter, InitializingBean {
@@ -355,8 +357,8 @@ public void write(Object source, final RedisData sink) {
355357
sink.setTimeToLive(ttl);
356358
}
357359

358-
for (IndexedData indexeData : indexResolver.resolveIndexesFor(entity.getTypeInformation(), source)) {
359-
sink.addIndexedData(indexeData);
360+
for (IndexedData indexedData : indexResolver.resolveIndexesFor(entity.getTypeInformation(), source)) {
361+
sink.addIndexedData(indexedData);
360362
}
361363

362364
}
@@ -409,8 +411,22 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper
409411
writeMap(keyspace, propertyStringPath, persistentProperty.getMapValueType(),
410412
(Map<?, ?>) accessor.getProperty(persistentProperty), sink);
411413
} else if (persistentProperty.isCollectionLike()) {
412-
writeCollection(keyspace, propertyStringPath, (Collection<?>) accessor.getProperty(persistentProperty),
414+
415+
final Object property = accessor.getProperty(persistentProperty);
416+
417+
if (property == null || Iterable.class.isAssignableFrom(property.getClass())) {
418+
419+
writeCollection(keyspace, propertyStringPath, (Iterable<?>) property,
413420
persistentProperty.getTypeInformation().getComponentType(), sink);
421+
} else if (property.getClass().isArray()) {
422+
423+
writeCollection(keyspace, propertyStringPath, Arrays.asList((Object[]) property),
424+
persistentProperty.getTypeInformation().getComponentType(), sink);
425+
} else {
426+
427+
throw new RuntimeException("Don't know how to handle " + property.getClass() + " type collection");
428+
}
429+
414430
} else if (persistentProperty.isEntity()) {
415431
writeInternal(keyspace, propertyStringPath, accessor.getProperty(persistentProperty),
416432
persistentProperty.getTypeInformation().getActualType(), sink);
@@ -482,7 +498,7 @@ public void doWithAssociation(Association<KeyValuePersistentProperty> associatio
482498
* @param typeHint
483499
* @param sink
484500
*/
485-
private void writeCollection(String keyspace, String path, Collection<?> values, TypeInformation<?> typeHint,
501+
private void writeCollection(String keyspace, String path, Iterable<?> values, TypeInformation<?> typeHint,
486502
RedisData sink) {
487503

488504
if (values == null) {
@@ -492,6 +508,10 @@ private void writeCollection(String keyspace, String path, Collection<?> values,
492508
int i = 0;
493509
for (Object value : values) {
494510

511+
if (value == null) {
512+
break;
513+
}
514+
495515
String currentPath = path + ".[" + i + "]";
496516

497517
if (customConversions.hasCustomWriteTarget(value.getClass())) {

src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
*/
1616
package org.springframework.data.redis.core.convert;
1717

18+
import java.util.Arrays;
1819
import java.util.Collections;
1920
import java.util.LinkedHashSet;
21+
import java.util.List;
2022
import java.util.Map;
2123
import java.util.Map.Entry;
2224
import java.util.Set;
@@ -43,6 +45,7 @@
4345
* {@link IndexConfiguration}.
4446
*
4547
* @author Christoph Strobl
48+
* @author Greg Turnquist
4649
* @since 1.7
4750
*/
4851
public class PathIndexResolver implements IndexResolver {
@@ -116,11 +119,23 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper
116119

117120
} else if (persistentProperty.isCollectionLike()) {
118121

119-
for (Object listValue : (Iterable<?>) propertyValue) {
122+
final Iterable<?> iterable;
120123

121-
TypeInformation<?> typeToUse = updateTypeHintForActualValue(typeHint, listValue);
122-
indexes.addAll(
124+
if (Iterable.class.isAssignableFrom(propertyValue.getClass())) {
125+
iterable = (Iterable) propertyValue;
126+
} else if (propertyValue.getClass().isArray()) {
127+
iterable = Arrays.asList((Object[]) propertyValue);
128+
} else {
129+
throw new RuntimeException("Don't know how to handle " + propertyValue.getClass() + " type of collection");
130+
}
131+
132+
for (Object listValue : iterable) {
133+
134+
if (listValue != null) {
135+
TypeInformation<?> typeToUse = updateTypeHintForActualValue(typeHint, listValue);
136+
indexes.addAll(
123137
doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), persistentProperty, listValue));
138+
}
124139
}
125140
}
126141

src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import java.util.Date;
4444
import java.util.HashMap;
4545
import java.util.LinkedHashMap;
46+
import java.util.List;
4647
import java.util.Map;
4748
import java.util.UUID;
4849

@@ -75,6 +76,7 @@
7576

7677
/**
7778
* @author Christoph Strobl
79+
* @author Greg Turnquist
7880
*/
7981
@RunWith(MockitoJUnitRunner.class)
8082
public class MappingRedisConverterUnitTests {
@@ -146,7 +148,7 @@ public void writeDoesNotAppendPropertiesWithNullValues() {
146148
* @see DATAREDIS-425
147149
*/
148150
@Test
149-
public void writeDoesNotAppendPropertiesWithEmtpyCollections() {
151+
public void writeDoesNotAppendPropertiesWithEmptyCollections() {
150152

151153
rand.firstname = "rand";
152154

@@ -435,6 +437,27 @@ public void writeAppendsMapWithSimpleKeyCorrectly() {
435437
.containingUtf8String("physicalAttributes.[eye-color]", "grey"));
436438
}
437439

440+
/**
441+
* @see DATAREDIS-492
442+
*/
443+
@Test
444+
public void writeHandlesArraysProperly() {
445+
446+
this.converter = new MappingRedisConverter(null, null, resolverMock);
447+
this.converter
448+
.setCustomConversions(new CustomConversions(Collections.singletonList(new ListToByteConverter())));
449+
this.converter.afterPropertiesSet();
450+
451+
Map<String, Object> innerMap = new LinkedHashMap<String, Object>();
452+
innerMap.put("address", "tyrionl@netflix.com");
453+
innerMap.put("when", new String[]{"pipeline.failed"});
454+
455+
Map<String, Object> map = new LinkedHashMap<String, Object>();
456+
map.put("email", Collections.singletonList(innerMap));
457+
458+
RedisData target = write(map);
459+
}
460+
438461
/**
439462
* @see DATAREDIS-425
440463
*/
@@ -1375,6 +1398,35 @@ public Map<String, byte[]> convert(Species source) {
13751398
}
13761399
}
13771400

1401+
@WritingConverter
1402+
static class ListToByteConverter implements Converter<List, byte[]> {
1403+
1404+
private final ObjectMapper mapper;
1405+
private final Jackson2JsonRedisSerializer<List> serializer;
1406+
1407+
ListToByteConverter() {
1408+
1409+
mapper = new ObjectMapper();
1410+
mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
1411+
.withFieldVisibility(Visibility.ANY).withGetterVisibility(Visibility.NONE)
1412+
.withSetterVisibility(Visibility.NONE).withCreatorVisibility(Visibility.NONE));
1413+
1414+
serializer = new Jackson2JsonRedisSerializer<List>(List.class);
1415+
serializer.setObjectMapper(mapper);
1416+
}
1417+
1418+
@Override
1419+
public byte[] convert(List source) {
1420+
1421+
if (source == null || source.isEmpty()) {
1422+
return null;
1423+
}
1424+
1425+
return serializer.serialize(source);
1426+
}
1427+
}
1428+
1429+
13781430
@ReadingConverter
13791431
static class MapToSpeciesConverter implements Converter<Map<String, byte[]>, Species> {
13801432

0 commit comments

Comments
 (0)