From 2d5c811ed29c8817fac217844760b6f554c1021f Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 6 May 2016 13:50:04 +0200 Subject: [PATCH 1/2] DATAREDIS-509 - Handle serializing arrays of primitives. Prepare issue branch. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e6d868411f..62b451b032 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-509-SNAPSHOT Spring Data Redis From e9e7fad53363e91a1b9528b533366c2774cc2ad7 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 6 May 2016 14:49:33 +0200 Subject: [PATCH 2/2] DATAREDIS-509 - Fix handling of primitive arrays in MappingRedisConverter. We now correctly convert arrays of primitive values. --- .../core/convert/MappingRedisConverter.java | 30 +++++++++++++++++-- .../redis/core/convert/PathIndexResolver.java | 12 ++++---- .../core/convert/ConversionTestEntities.java | 1 + .../MappingRedisConverterUnitTests.java | 30 +++++++++++++++++++ 4 files changed, 64 insertions(+), 9 deletions(-) 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 bff2eb4e8f..c503e71fea 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 @@ -17,11 +17,11 @@ import java.lang.reflect.Array; import java.util.ArrayList; -import java.util.Arrays; 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.Map.Entry; @@ -426,7 +426,7 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper persistentProperty.getTypeInformation().getComponentType(), sink); } else if (property.getClass().isArray()) { - writeCollection(keyspace, propertyStringPath, Arrays.asList((Object[]) property), + writeCollection(keyspace, propertyStringPath, CollectionUtils.arrayToList(property), persistentProperty.getTypeInformation().getComponentType(), sink); } else { @@ -592,7 +592,7 @@ private Object readCollectionOrArray(String path, Class collectionType, Class } } - return isArray ? target.toArray((Object[]) Array.newInstance(valueType, target.size())) : target; + return isArray ? toArray(target, collectionType, valueType) : target; } /** @@ -749,6 +749,30 @@ public T fromBytes(byte[] source, Class type) { return conversionService.convert(source, type); } + /** + * Converts a given {@link Collection} into an array considering primitive types. + * + * @param source {@link Collection} of values to be added to the array. + * @param arrayType {@link Class} of array. + * @param valueType to be used for conversion before setting the actual value. + * @return + */ + private Object toArray(Collection source, Class arrayType, Class valueType) { + + if (!ClassUtils.isPrimitiveArray(arrayType)) { + return source.toArray((Object[]) Array.newInstance(valueType, source.size())); + } + + Object targetArray = Array.newInstance(valueType, source.size()); + Iterator iterator = source.iterator(); + int i = 0; + while (iterator.hasNext()) { + Array.set(targetArray, i, conversionService.convert(iterator.next(), valueType)); + i++; + } + return targetArray; + } + /** * Set {@link CustomConversions} to be applied. * 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 cd31ee665d..eeaf6a931a 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,10 +15,8 @@ */ 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; @@ -39,6 +37,7 @@ import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; /** * {@link IndexResolver} implementation considering properties annotated with {@link Indexed} or paths set up in @@ -124,17 +123,18 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper if (Iterable.class.isAssignableFrom(propertyValue.getClass())) { iterable = (Iterable) propertyValue; } else if (propertyValue.getClass().isArray()) { - iterable = Arrays.asList((Object[]) propertyValue); + iterable = CollectionUtils.arrayToList(propertyValue); } else { - throw new RuntimeException("Don't know how to handle " + propertyValue.getClass() + " type of collection"); + 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)); + indexes.addAll(doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), persistentProperty, + listValue)); } } } 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 ecd55cc97b..d3903ec9b4 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 @@ -167,6 +167,7 @@ public static class WithArrays { Object[] arrayOfObject; String[] arrayOfSimpleTypes; Species[] arrayOfCompexTypes; + int[] arrayOfPrimitives; } static class TypeWithObjectValueTypes { 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 5a7a1fae4c..867c58a141 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 @@ -1581,6 +1581,36 @@ public void shouldWriteReadObjectListValueTypeCorrectly() { assertThat(result.list.get(2), instanceOf(Date.class)); } + /** + * @see DATAREDIS-509 + */ + @Test + public void writeHandlesArraysOfPrimitivesProperly() { + + Map source = new LinkedHashMap(); + source.put("arrayOfPrimitives.[0]", "1"); + source.put("arrayOfPrimitives.[1]", "2"); + source.put("arrayOfPrimitives.[2]", "3"); + + WithArrays target = read(WithArrays.class, source); + + assertThat(target.arrayOfPrimitives[0], is(1)); + assertThat(target.arrayOfPrimitives[1], is(2)); + assertThat(target.arrayOfPrimitives[2], is(3)); + } + + /** + * @see DATAREDIS-509 + */ + @Test + public void readHandlesArraysOfPrimitivesProperly() { + + WithArrays source = new WithArrays(); + source.arrayOfPrimitives = new int[] { 1, 2, 3 }; + assertThat(write(source).getBucket(), isBucket().containingUtf8String("arrayOfPrimitives.[0]", "1") + .containingUtf8String("arrayOfPrimitives.[1]", "2").containingUtf8String("arrayOfPrimitives.[2]", "3")); + } + private RedisData write(Object source) { RedisData rdo = new RedisData();