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 27a298922..b3c4331d6 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 @@ -117,6 +117,7 @@ import com.mongodb.DBRef; * @author Roman Puchkovskiy * @author Heesu Jung * @author Divya Srivastava + * @author Julia Lee */ public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware { @@ -1978,8 +1979,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } 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 ca9993eb6..8709b8d9c 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 @@ -62,6 +62,7 @@ import com.mongodb.client.model.Filters; * {@link DocumentReference} related integration tests for {@link MongoTemplate}. * * @author Christoph Strobl + * @author Julia Lee */ @ExtendWith(MongoClientExtension.class) public class MongoTemplateDocumentReferenceTests { @@ -1270,6 +1271,32 @@ public class MongoTemplateDocumentReferenceTests { .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); + } + @Data static class SingleRefRoot { @@ -1614,4 +1641,40 @@ public class MongoTemplateDocumentReferenceTests { @DocumentReference private List refs; } + + 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() + ")"; + } + } }