From e3e73f535170050189d318ea943a78f2fa8dae05 Mon Sep 17 00:00:00 2001 From: Julia <5765049+sxhinzvc@users.noreply.github.com> Date: Mon, 28 Aug 2023 16:19:47 -0400 Subject: [PATCH] Fix `#self` @DocumentReference resolution when used in constructor. This commit enables document reference lookup to use `DocumentReferenceSource` to properly instantiate an entity containig a @DocumentReference `#self` property. Closes #4484 Original Pull Request: #4486 --- .../core/convert/MappingMongoConverter.java | 6 +- .../MongoTemplateDocumentReferenceTests.java | 63 +++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index 2bfb90150c..6aeb08e240 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -98,6 +98,7 @@ * @author Roman Puchkovskiy * @author Heesu Jung * @author Divya Srivastava + * @author Julia Lee */ public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware { @@ -1976,8 +1977,9 @@ public T getPropertyValue(MongoPersistentProperty property) { } if (property.isDocumentReference()) { - return (T) dbRefResolver.resolveReference(property, accessor.get(property), referenceLookupDelegate, - context::convert); + return (T) dbRefResolver.resolveReference(property, + new DocumentReferenceSource(accessor.getDocument(), accessor.get(property)), + referenceLookupDelegate, context::convert); } return super.getPropertyValue(property); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java index 8693f027db..c502533b37 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateDocumentReferenceTests.java @@ -57,6 +57,7 @@ * {@link DocumentReference} related integration tests for {@link MongoTemplate}. * * @author Christoph Strobl + * @author Julia Lee */ @ExtendWith(MongoClientExtension.class) public class MongoTemplateDocumentReferenceTests { @@ -1265,6 +1266,32 @@ void readWriteTypeReferenceHavingFixedStringIdTargetType() { .isEqualTo(new ObjectRefHavingStringIdTargetType(id.toHexString(), "me-the-referenced-object")); } + @Test // GH-4484 + void resolveReferenceForOneToManyLookupWithSelfVariableWhenUsedInCtorArgument() { + + OneToManyStylePublisherWithRequiredArgsCtor publisher = new OneToManyStylePublisherWithRequiredArgsCtor("p-100", null); + template.save(publisher); + + OneToManyStyleBook book1 = new OneToManyStyleBook(); + book1.id = "id-1"; + book1.publisherId = publisher.id; + + OneToManyStyleBook book2 = new OneToManyStyleBook(); + book2.id = "id-2"; + book2.publisherId = "p-200"; + + OneToManyStyleBook book3 = new OneToManyStyleBook(); + book3.id = "id-3"; + book3.publisherId = publisher.id; + + template.save(book1); + template.save(book2); + template.save(book3); + + OneToManyStylePublisherWithRequiredArgsCtor target = template.findOne(query(where("id").is(publisher.id)), OneToManyStylePublisherWithRequiredArgsCtor.class); + assertThat(target.books).containsExactlyInAnyOrder(book1, book3); + } + static class SingleRefRoot { String id; @@ -2249,4 +2276,40 @@ public String toString() { return "MongoTemplateDocumentReferenceTests.WithListOfRefs(id=" + this.getId() + ", refs=" + this.getRefs() + ")"; } } + + static class OneToManyStylePublisherWithRequiredArgsCtor { + + @Id + String id; + + @ReadOnlyProperty + @DocumentReference(lookup="{'publisherId':?#{#self._id} }") + List books; + + public OneToManyStylePublisherWithRequiredArgsCtor(String id, List books) { + this.id = id; + this.books = books; + } + + public String getId() { + return this.id; + } + + public List getBooks() { + return this.books; + } + + public void setId(String id) { + this.id = id; + } + + public void setBooks(List books) { + this.books = books; + } + + public String toString() { + return "MongoTemplateDocumentReferenceTests.OneToManyStylePublisherWithRequiredArgsCtor(id=" + this.getId() + ", book=" + + this.getBooks() + ")"; + } + } }