Skip to content

Commit 5e6d236

Browse files
christophstroblmp911de
authored andcommitted
DATAREDIS-509 - Fix handling of primitive arrays in MappingRedisConverter.
We now correctly convert arrays of primitive values. Original pull request: #196.
1 parent f079833 commit 5e6d236

File tree

4 files changed

+64
-9
lines changed

4 files changed

+64
-9
lines changed

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

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717

1818
import java.lang.reflect.Array;
1919
import java.util.ArrayList;
20-
import java.util.Arrays;
2120
import java.util.Collection;
2221
import java.util.Collections;
2322
import java.util.Comparator;
2423
import java.util.HashMap;
24+
import java.util.Iterator;
2525
import java.util.List;
2626
import java.util.Map;
2727
import java.util.Map.Entry;
@@ -418,7 +418,7 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper
418418
persistentProperty.getTypeInformation().getComponentType(), sink);
419419
} else if (property.getClass().isArray()) {
420420

421-
writeCollection(keyspace, propertyStringPath, Arrays.asList((Object[]) property),
421+
writeCollection(keyspace, propertyStringPath, CollectionUtils.arrayToList(property),
422422
persistentProperty.getTypeInformation().getComponentType(), sink);
423423
} else {
424424

@@ -584,7 +584,7 @@ private Object readCollectionOrArray(String path, Class<?> collectionType, Class
584584
}
585585
}
586586

587-
return isArray ? target.toArray((Object[]) Array.newInstance(valueType, target.size())) : target;
587+
return isArray ? toArray(target, collectionType, valueType) : target;
588588
}
589589

590590
/**
@@ -741,6 +741,30 @@ public <T> T fromBytes(byte[] source, Class<T> type) {
741741
return conversionService.convert(source, type);
742742
}
743743

744+
/**
745+
* Converts a given {@link Collection} into an array considering primitive types.
746+
*
747+
* @param source {@link Collection} of values to be added to the array.
748+
* @param arrayType {@link Class} of array.
749+
* @param valueType to be used for conversion before setting the actual value.
750+
* @return
751+
*/
752+
private Object toArray(Collection<Object> source, Class<?> arrayType, Class<?> valueType) {
753+
754+
if (!ClassUtils.isPrimitiveArray(arrayType)) {
755+
return source.toArray((Object[]) Array.newInstance(valueType, source.size()));
756+
}
757+
758+
Object targetArray = Array.newInstance(valueType, source.size());
759+
Iterator<Object> iterator = source.iterator();
760+
int i = 0;
761+
while (iterator.hasNext()) {
762+
Array.set(targetArray, i, conversionService.convert(iterator.next(), valueType));
763+
i++;
764+
}
765+
return targetArray;
766+
}
767+
744768
/**
745769
* Set {@link CustomConversions} to be applied.
746770
*

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

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

18-
import java.util.Arrays;
1918
import java.util.Collections;
2019
import java.util.LinkedHashSet;
21-
import java.util.List;
2220
import java.util.Map;
2321
import java.util.Map.Entry;
2422
import java.util.Set;
@@ -39,6 +37,7 @@
3937
import org.springframework.data.util.ClassTypeInformation;
4038
import org.springframework.data.util.TypeInformation;
4139
import org.springframework.util.Assert;
40+
import org.springframework.util.CollectionUtils;
4241

4342
/**
4443
* {@link IndexResolver} implementation considering properties annotated with {@link Indexed} or paths set up in
@@ -124,17 +123,18 @@ public void doWithPersistentProperty(KeyValuePersistentProperty persistentProper
124123
if (Iterable.class.isAssignableFrom(propertyValue.getClass())) {
125124
iterable = (Iterable) propertyValue;
126125
} else if (propertyValue.getClass().isArray()) {
127-
iterable = Arrays.asList((Object[]) propertyValue);
126+
iterable = CollectionUtils.arrayToList(propertyValue);
128127
} else {
129-
throw new RuntimeException("Don't know how to handle " + propertyValue.getClass() + " type of collection");
128+
throw new RuntimeException(
129+
"Don't know how to handle " + propertyValue.getClass() + " type of collection");
130130
}
131131

132132
for (Object listValue : iterable) {
133133

134134
if (listValue != null) {
135135
TypeInformation<?> typeToUse = updateTypeHintForActualValue(typeHint, listValue);
136-
indexes.addAll(
137-
doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), persistentProperty, listValue));
136+
indexes.addAll(doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), persistentProperty,
137+
listValue));
138138
}
139139
}
140140
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ public static class WithArrays {
167167
Object[] arrayOfObject;
168168
String[] arrayOfSimpleTypes;
169169
Species[] arrayOfCompexTypes;
170+
int[] arrayOfPrimitives;
170171
}
171172

172173
static class TypeWithObjectValueTypes {

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,6 +1581,36 @@ public void shouldWriteReadObjectListValueTypeCorrectly() {
15811581
assertThat(result.list.get(2), instanceOf(Date.class));
15821582
}
15831583

1584+
/**
1585+
* @see DATAREDIS-509
1586+
*/
1587+
@Test
1588+
public void writeHandlesArraysOfPrimitivesProperly() {
1589+
1590+
Map<String, String> source = new LinkedHashMap<String, String>();
1591+
source.put("arrayOfPrimitives.[0]", "1");
1592+
source.put("arrayOfPrimitives.[1]", "2");
1593+
source.put("arrayOfPrimitives.[2]", "3");
1594+
1595+
WithArrays target = read(WithArrays.class, source);
1596+
1597+
assertThat(target.arrayOfPrimitives[0], is(1));
1598+
assertThat(target.arrayOfPrimitives[1], is(2));
1599+
assertThat(target.arrayOfPrimitives[2], is(3));
1600+
}
1601+
1602+
/**
1603+
* @see DATAREDIS-509
1604+
*/
1605+
@Test
1606+
public void readHandlesArraysOfPrimitivesProperly() {
1607+
1608+
WithArrays source = new WithArrays();
1609+
source.arrayOfPrimitives = new int[] { 1, 2, 3 };
1610+
assertThat(write(source).getBucket(), isBucket().containingUtf8String("arrayOfPrimitives.[0]", "1")
1611+
.containingUtf8String("arrayOfPrimitives.[1]", "2").containingUtf8String("arrayOfPrimitives.[2]", "3"));
1612+
}
1613+
15841614
private RedisData write(Object source) {
15851615

15861616
RedisData rdo = new RedisData();

0 commit comments

Comments
 (0)