Skip to content

Commit 5f33987

Browse files
christophstroblmp911de
authored andcommitted
Fix issue with reference conversion in updates.
We now make sure to convert references in update operations targeting collection like fields when using eg. the push modifier. Closes #4041 Original pull request: #4045.
1 parent f7cf235 commit 5f33987

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/UpdateMapper.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
*/
1616
package org.springframework.data.mongodb.core.convert;
1717

18+
import java.util.ArrayList;
1819
import java.util.Collection;
1920
import java.util.LinkedHashMap;
21+
import java.util.List;
2022
import java.util.Map.Entry;
2123

2224
import org.bson.Document;
@@ -34,6 +36,7 @@
3436
import org.springframework.data.util.ClassTypeInformation;
3537
import org.springframework.data.util.TypeInformation;
3638
import org.springframework.lang.Nullable;
39+
import org.springframework.util.ObjectUtils;
3740

3841
/**
3942
* A subclass of {@link QueryMapper} that retains type information on the mongo types.
@@ -221,8 +224,18 @@ private Object getMappedModifier(@Nullable Field field, Modifier modifier) {
221224
: getMappedSort(sortObject, field.getPropertyEntity());
222225
}
223226

224-
TypeInformation<?> typeHint = field == null ? ClassTypeInformation.OBJECT : field.getTypeHint();
227+
if (isAssociationConversionNecessary(field, value)) {
228+
if (ObjectUtils.isArray(value) || value instanceof Collection) {
229+
List<Object> targetPointers = new ArrayList<>();
230+
for (Object val : converter.getConversionService().convert(value, List.class)) {
231+
targetPointers.add(getMappedValue(field, val));
232+
}
233+
return targetPointers;
234+
}
235+
return super.getMappedValue(field, value);
236+
}
225237

238+
TypeInformation<?> typeHint = field == null ? ClassTypeInformation.OBJECT : field.getTypeHint();
226239
return converter.convertToMongoType(value, typeHint);
227240
}
228241

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java

+30
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,29 @@ void updateReferenceWithValue() {
903903
assertThat(target).containsEntry("toB", "b");
904904
}
905905

906+
@Test // GH-4041
907+
void updateReferenceWithPushToCollection() {
908+
909+
WithListOfRefs a = new WithListOfRefs();
910+
a.id = "a";
911+
template.save(a);
912+
913+
WithListOfRefs b = new WithListOfRefs();
914+
b.id = "b";
915+
template.save(b);
916+
917+
template.update(WithListOfRefs.class).matching(where("id").is(a.id))
918+
.apply(new Update().push("refs").each(new Object[] { b })).first();
919+
920+
String collection = template.getCollectionName(WithListOfRefs.class);
921+
922+
Document target = template.execute(db -> {
923+
return db.getCollection(collection).find(Filters.eq("_id", "a")).first();
924+
});
925+
926+
assertThat(target).containsEntry("refs", Collections.singletonList("b"));
927+
}
928+
906929
@Test // GH-3782
907930
void updateReferenceHavingCustomizedIdTargetType() {
908931

@@ -1584,4 +1607,11 @@ public Publisher getPublisher() {
15841607
return publisher;
15851608
}
15861609
}
1610+
1611+
@Data
1612+
public static class WithListOfRefs {
1613+
@Id private String id;
1614+
1615+
@DocumentReference private List<WithListOfRefs> refs;
1616+
}
15871617
}

0 commit comments

Comments
 (0)