Skip to content

Commit 05a4d58

Browse files
Add update tests
Next give some repository methods a spin and then we'd be good to go I think :)
1 parent 637cec9 commit 05a4d58

File tree

2 files changed

+202
-5
lines changed

2 files changed

+202
-5
lines changed

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -598,12 +598,22 @@ public Object toDocumentReference(Object source, @Nullable MongoPersistentProper
598598

599599
Object createDocumentPointer(Object source, @Nullable MongoPersistentProperty referringProperty) {
600600

601-
if (conversionService.canConvert(referringProperty.getType(), DocumentPointer.class)) {
601+
if (referringProperty == null) {
602+
return source;
603+
}
604+
605+
if (ClassUtils.isAssignableValue(referringProperty.getType(), source)
606+
&& conversionService.canConvert(referringProperty.getType(), DocumentPointer.class)) {
602607
return conversionService.convert(source, DocumentPointer.class).getPointer();
603608
}
604609

605-
return mappingContext.getPersistentEntity(referringProperty.getAssociationTargetType())
606-
.getIdentifierAccessor(source).getIdentifier();
610+
if (ClassUtils.isAssignableValue(referringProperty.getAssociationTargetType(), source)) {
611+
return mappingContext.getPersistentEntity(referringProperty.getAssociationTargetType())
612+
.getIdentifierAccessor(source).getIdentifier();
613+
614+
}
615+
616+
return source;
607617
}
608618

609619
/**

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

Lines changed: 189 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.Map;
3333

3434
import org.bson.Document;
35+
import org.junit.Ignore;
3536
import org.junit.jupiter.api.BeforeEach;
3637
import org.junit.jupiter.api.Test;
3738
import org.junit.jupiter.api.extension.ExtendWith;
@@ -42,6 +43,7 @@
4243
import org.springframework.data.mongodb.core.mapping.DocumentPointer;
4344
import org.springframework.data.mongodb.core.mapping.DocumentReference;
4445
import org.springframework.data.mongodb.core.mapping.Field;
46+
import org.springframework.data.mongodb.core.query.Update;
4547
import org.springframework.data.mongodb.test.util.Client;
4648
import org.springframework.data.mongodb.test.util.MongoClientExtension;
4749
import org.springframework.data.mongodb.test.util.MongoTestTemplate;
@@ -587,8 +589,6 @@ void loadCollectionReferenceWithMissingRefs() {
587589
@Test // GH-3602
588590
void queryForReference() {
589591

590-
String collectionB = template.getCollectionName(WithRefB.class);
591-
592592
WithRefB b = new WithRefB();
593593
b.id = "b";
594594
template.save(b);
@@ -606,6 +606,193 @@ void queryForReference() {
606606
assertThat(loadedA.getId()).isEqualTo(a.getId());
607607
}
608608

609+
@Test // GH-3602
610+
void queryForReferenceInCollection() {
611+
612+
String rootCollectionName = template.getCollectionName(CollectionRefRoot.class);
613+
614+
Document shouldBeFound = new Document("_id", "id-1").append("value", "v1").append("simpleValueRef",
615+
Arrays.asList("ref-1", "ref-2"));
616+
Document shouldNotBeFound = new Document("_id", "id-2").append("value", "v2").append("simpleValueRef",
617+
Arrays.asList("ref-1"));
618+
619+
template.execute(db -> {
620+
621+
db.getCollection(rootCollectionName).insertOne(shouldBeFound);
622+
db.getCollection(rootCollectionName).insertOne(shouldNotBeFound);
623+
return null;
624+
});
625+
626+
SimpleObjectRef objectRef = new SimpleObjectRef("ref-2", "some irrelevant value");
627+
628+
List<CollectionRefRoot> loaded = template.query(CollectionRefRoot.class)
629+
.matching(where("simpleValueRef").in(objectRef)).all();
630+
assertThat(loaded).map(CollectionRefRoot::getId).containsExactly("id-1");
631+
}
632+
633+
@Test // GH-3602
634+
void queryForReferenceOnIdField() {
635+
636+
WithRefB b = new WithRefB();
637+
b.id = "b";
638+
template.save(b);
639+
640+
WithRefA a = new WithRefA();
641+
a.id = "a";
642+
a.toB = b;
643+
template.save(a);
644+
645+
WithRefA a2 = new WithRefA();
646+
a2.id = "a2";
647+
template.save(a2);
648+
649+
WithRefA loadedA = template.query(WithRefA.class).matching(where("toB.id").is(b.id)).firstValue();
650+
assertThat(loadedA.getId()).isEqualTo(a.getId());
651+
}
652+
653+
@Test // GH-3602
654+
void updateReferenceWithEntityHavingPointerConversion() {
655+
656+
WithRefB b = new WithRefB();
657+
b.id = "b";
658+
template.save(b);
659+
660+
WithRefA a = new WithRefA();
661+
a.id = "a";
662+
template.save(a);
663+
664+
template.update(WithRefA.class).apply(new Update().set("toB", b)).first();
665+
666+
String collectionA = template.getCollectionName(WithRefA.class);
667+
668+
Document target = template.execute(db -> {
669+
return db.getCollection(collectionA).find(Filters.eq("_id", "a")).first();
670+
});
671+
672+
assertThat(target).containsEntry("toB", "b");
673+
}
674+
675+
@Test // GH-3602
676+
void updateReferenceWithEntityWithoutPointerConversion() {
677+
678+
String collectionName = template.getCollectionName(SingleRefRoot.class);
679+
SingleRefRoot refRoot = new SingleRefRoot();
680+
refRoot.id = "root-1";
681+
682+
SimpleObjectRef ref = new SimpleObjectRef("ref-1", "me the referenced object");
683+
684+
template.save(refRoot);
685+
686+
template.update(SingleRefRoot.class).apply(new Update().set("simpleValueRef", ref)).first();
687+
688+
Document target = template.execute(db -> {
689+
return db.getCollection(collectionName).find(Filters.eq("_id", "root-1")).first();
690+
});
691+
692+
assertThat(target).containsEntry("simpleValueRef", "ref-1");
693+
}
694+
695+
@Test // GH-3602
696+
void updateReferenceWithValue() {
697+
698+
WithRefA a = new WithRefA();
699+
a.id = "a";
700+
template.save(a);
701+
702+
template.update(WithRefA.class).apply(new Update().set("toB", "b")).first();
703+
704+
String collectionA = template.getCollectionName(WithRefA.class);
705+
706+
Document target = template.execute(db -> {
707+
return db.getCollection(collectionA).find(Filters.eq("_id", "a")).first();
708+
});
709+
710+
assertThat(target).containsEntry("toB", "b");
711+
}
712+
713+
@Test // GH-3602
714+
void updateReferenceCollectionWithEntity() {
715+
716+
String rootCollectionName = template.getCollectionName(CollectionRefRoot.class);
717+
718+
CollectionRefRoot root = new CollectionRefRoot();
719+
root.id = "root-1";
720+
root.simpleValueRef = Collections.singletonList(new SimpleObjectRef("ref-1", "beastie"));
721+
722+
template.save(root);
723+
724+
template.update(CollectionRefRoot.class)
725+
.apply(new Update().push("simpleValueRef").value(new SimpleObjectRef("ref-2", "boys"))).first();
726+
727+
Document target = template.execute(db -> {
728+
return db.getCollection(rootCollectionName).find(Filters.eq("_id", "root-1")).first();
729+
});
730+
731+
assertThat(target).containsEntry("simpleValueRef", Arrays.asList("ref-1", "ref-2"));
732+
}
733+
734+
@Test // GH-3602
735+
void updateReferenceCollectionWithValue() {
736+
737+
String rootCollectionName = template.getCollectionName(CollectionRefRoot.class);
738+
739+
CollectionRefRoot root = new CollectionRefRoot();
740+
root.id = "root-1";
741+
root.simpleValueRef = Collections.singletonList(new SimpleObjectRef("ref-1", "beastie"));
742+
743+
template.save(root);
744+
745+
template.update(CollectionRefRoot.class).apply(new Update().push("simpleValueRef").value("ref-2")).first();
746+
747+
Document target = template.execute(db -> {
748+
return db.getCollection(rootCollectionName).find(Filters.eq("_id", "root-1")).first();
749+
});
750+
751+
assertThat(target).containsEntry("simpleValueRef", Arrays.asList("ref-1", "ref-2"));
752+
}
753+
754+
@Test // GH-3602
755+
@Ignore("Property path resolution does not work inside maps, the key is considered :/")
756+
void updateReferenceMapWithEntity() {
757+
758+
String rootCollectionName = template.getCollectionName(CollectionRefRoot.class);
759+
760+
CollectionRefRoot root = new CollectionRefRoot();
761+
root.id = "root-1";
762+
root.mapValueRef = Collections.singletonMap("beastie", new SimpleObjectRef("ref-1", "boys"));
763+
764+
template.save(root);
765+
766+
template.update(CollectionRefRoot.class)
767+
.apply(new Update().set("mapValueRef.rise", new SimpleObjectRef("ref-2", "against"))).first();
768+
769+
Document target = template.execute(db -> {
770+
return db.getCollection(rootCollectionName).find(Filters.eq("_id", "root-1")).first();
771+
});
772+
773+
assertThat(target).containsEntry("mapValueRef", new Document("beastie", "ref-1").append("rise", "ref-2"));
774+
}
775+
776+
@Test // GH-3602
777+
void updateReferenceMapWithValue() {
778+
779+
String rootCollectionName = template.getCollectionName(CollectionRefRoot.class);
780+
781+
CollectionRefRoot root = new CollectionRefRoot();
782+
root.id = "root-1";
783+
root.mapValueRef = Collections.singletonMap("beastie", new SimpleObjectRef("ref-1", "boys"));
784+
785+
template.save(root);
786+
787+
template.update(CollectionRefRoot.class).apply(new Update().set("mapValueRef.rise", "ref-2")).first();
788+
789+
Document target = template.execute(db -> {
790+
return db.getCollection(rootCollectionName).find(Filters.eq("_id", "root-1")).first();
791+
});
792+
793+
assertThat(target).containsEntry("mapValueRef", new Document("beastie", "ref-1").append("rise", "ref-2"));
794+
}
795+
609796
@Data
610797
static class SingleRefRoot {
611798

0 commit comments

Comments
 (0)