diff --git a/pom.xml b/pom.xml
index e6d868411f..8ea9f36d37 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-redis
- 1.8.0.BUILD-SNAPSHOT
+ 1.8.0.DATAREDIS-492-SNAPSHOT
Spring Data Redis
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 87f16256e9..eb90a37b42 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
@@ -16,6 +16,7 @@
package org.springframework.data.redis.core.convert;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
@@ -99,6 +100,7 @@
*
*
* @author Christoph Strobl
+ * @author Greg Turnquist
* @since 1.7
*/
public class MappingRedisConverter implements RedisConverter, InitializingBean {
@@ -354,8 +356,8 @@ public void write(Object source, final RedisData sink) {
sink.setTimeToLive(ttl);
}
- for (IndexedData indexeData : indexResolver.resolveIndexesFor(entity.getTypeInformation(), source)) {
- sink.addIndexedData(indexeData);
+ for (IndexedData indexedData : indexResolver.resolveIndexesFor(entity.getTypeInformation(), source)) {
+ sink.addIndexedData(indexedData);
}
}
@@ -408,8 +410,22 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper
writeMap(keyspace, propertyStringPath, persistentProperty.getMapValueType(),
(Map, ?>) accessor.getProperty(persistentProperty), sink);
} else if (persistentProperty.isCollectionLike()) {
- writeCollection(keyspace, propertyStringPath, (Collection>) accessor.getProperty(persistentProperty),
+
+ final Object property = accessor.getProperty(persistentProperty);
+
+ if (property == null || Iterable.class.isAssignableFrom(property.getClass())) {
+
+ writeCollection(keyspace, propertyStringPath, (Iterable>) property,
persistentProperty.getTypeInformation().getComponentType(), sink);
+ } else if (property.getClass().isArray()) {
+
+ writeCollection(keyspace, propertyStringPath, Arrays.asList((Object[]) property),
+ persistentProperty.getTypeInformation().getComponentType(), sink);
+ } else {
+
+ throw new RuntimeException("Don't know how to handle " + property.getClass() + " type collection");
+ }
+
} else if (persistentProperty.isEntity()) {
writeInternal(keyspace, propertyStringPath, accessor.getProperty(persistentProperty),
persistentProperty.getTypeInformation().getActualType(), sink);
@@ -481,7 +497,7 @@ public void doWithAssociation(Association associatio
* @param typeHint
* @param sink
*/
- private void writeCollection(String keyspace, String path, Collection> values, TypeInformation> typeHint,
+ private void writeCollection(String keyspace, String path, Iterable> values, TypeInformation> typeHint,
RedisData sink) {
if (values == null) {
@@ -491,6 +507,10 @@ private void writeCollection(String keyspace, String path, Collection> values,
int i = 0;
for (Object value : values) {
+ if (value == null) {
+ break;
+ }
+
String currentPath = path + ".[" + i + "]";
if (customConversions.hasCustomWriteTarget(value.getClass())) {
diff --git a/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java b/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java
index 94c5334215..cd31ee665d 100644
--- a/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java
+++ b/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java
@@ -15,8 +15,10 @@
*/
package org.springframework.data.redis.core.convert;
+import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -43,6 +45,7 @@
* {@link IndexConfiguration}.
*
* @author Christoph Strobl
+ * @author Greg Turnquist
* @since 1.7
*/
public class PathIndexResolver implements IndexResolver {
@@ -116,11 +119,23 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper
} else if (persistentProperty.isCollectionLike()) {
- for (Object listValue : (Iterable>) propertyValue) {
+ final Iterable> iterable;
- TypeInformation> typeToUse = updateTypeHintForActualValue(typeHint, listValue);
- indexes.addAll(
+ if (Iterable.class.isAssignableFrom(propertyValue.getClass())) {
+ iterable = (Iterable) propertyValue;
+ } else if (propertyValue.getClass().isArray()) {
+ iterable = Arrays.asList((Object[]) propertyValue);
+ } else {
+ throw new RuntimeException("Don't know how to handle " + propertyValue.getClass() + " type of collection");
+ }
+
+ for (Object listValue : iterable) {
+
+ if (listValue != null) {
+ TypeInformation> typeToUse = updateTypeHintForActualValue(typeHint, listValue);
+ indexes.addAll(
doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), persistentProperty, listValue));
+ }
}
}
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 3b655dc6b7..df88ffd35b 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
@@ -43,6 +43,7 @@
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -75,6 +76,7 @@
/**
* @author Christoph Strobl
+ * @author Greg Turnquist
*/
@RunWith(MockitoJUnitRunner.class)
public class MappingRedisConverterUnitTests {
@@ -146,7 +148,7 @@ public void writeDoesNotAppendPropertiesWithNullValues() {
* @see DATAREDIS-425
*/
@Test
- public void writeDoesNotAppendPropertiesWithEmtpyCollections() {
+ public void writeDoesNotAppendPropertiesWithEmptyCollections() {
rand.firstname = "rand";
@@ -435,6 +437,27 @@ public void writeAppendsMapWithSimpleKeyCorrectly() {
.containingUtf8String("physicalAttributes.[eye-color]", "grey"));
}
+ /**
+ * @see DATAREDIS-492
+ */
+ @Test
+ public void writeHandlesArraysProperly() {
+
+ this.converter = new MappingRedisConverter(null, null, resolverMock);
+ this.converter
+ .setCustomConversions(new CustomConversions(Collections.singletonList(new ListToByteConverter())));
+ this.converter.afterPropertiesSet();
+
+ Map innerMap = new LinkedHashMap();
+ innerMap.put("address", "tyrionl@netflix.com");
+ innerMap.put("when", new String[]{"pipeline.failed"});
+
+ Map map = new LinkedHashMap();
+ map.put("email", Collections.singletonList(innerMap));
+
+ RedisData target = write(map);
+ }
+
/**
* @see DATAREDIS-425
*/
@@ -1375,6 +1398,35 @@ public Map convert(Species source) {
}
}
+ @WritingConverter
+ static class ListToByteConverter implements Converter {
+
+ private final ObjectMapper mapper;
+ private final Jackson2JsonRedisSerializer serializer;
+
+ ListToByteConverter() {
+
+ mapper = new ObjectMapper();
+ mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
+ .withFieldVisibility(Visibility.ANY).withGetterVisibility(Visibility.NONE)
+ .withSetterVisibility(Visibility.NONE).withCreatorVisibility(Visibility.NONE));
+
+ serializer = new Jackson2JsonRedisSerializer(List.class);
+ serializer.setObjectMapper(mapper);
+ }
+
+ @Override
+ public byte[] convert(List source) {
+
+ if (source == null || source.isEmpty()) {
+ return null;
+ }
+
+ return serializer.serialize(source);
+ }
+ }
+
+
@ReadingConverter
static class MapToSpeciesConverter implements Converter