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 5c0a42a3b..435ab1316 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 @@ -264,8 +264,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App accessor.setProperty(idProperty, idValue); } - final ObjectPath currentPath = path.push(result, entity, idValue != null ? dbo.get(idProperty.getFieldName()) - : null); + final ObjectPath currentPath = path.push(result, entity, + idValue != null ? dbo.get(idProperty.getFieldName()) : null); // Set properties not already set in the constructor entity.doWithProperties(new PropertyHandler() { @@ -291,7 +291,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App final MongoPersistentProperty property = association.getInverse(); Object value = dbo.get(property.getFieldName()); - if (value == null) { + if (value == null || (entity.isConstructorArgument(property) && accessor.getProperty(property) != null)) { return; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index 920c5a957..1feec6553 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -3074,6 +3074,75 @@ public class MongoTemplateTests { assertThat(contentLoaded.dbrefMessage.id, is(messageLoaded.id)); } + /** + * @see DATAMONGO-1287 + */ + @Test + public void shouldReuseAlreadyResolvedLazyLoadedDBRefWhenUsedAsPersistenceConstrcutorArgument() { + + Document docInCtor = new Document(); + docInCtor.id = "doc-in-ctor"; + template.save(docInCtor); + + DocumentWithLazyDBrefUsedInPresistenceConstructor source = new DocumentWithLazyDBrefUsedInPresistenceConstructor( + docInCtor); + + template.save(source); + + DocumentWithLazyDBrefUsedInPresistenceConstructor loaded = template.findOne(query(where("id").is(source.id)), + DocumentWithLazyDBrefUsedInPresistenceConstructor.class); + assertThat(loaded.refToDocUsedInCtor, not(instanceOf(LazyLoadingProxy.class))); + assertThat(loaded.refToDocNotUsedInCtor, nullValue()); + } + + /** + * @see DATAMONGO-1287 + */ + @Test + public void shouldNotReuseLazyLoadedDBRefWhenTypeUsedInPersistenceConstrcutorButValueRefersToAnotherProperty() { + + Document docNotUsedInCtor = new Document(); + docNotUsedInCtor.id = "doc-but-not-used-in-ctor"; + template.save(docNotUsedInCtor); + + DocumentWithLazyDBrefUsedInPresistenceConstructor source = new DocumentWithLazyDBrefUsedInPresistenceConstructor( + null); + source.refToDocNotUsedInCtor = docNotUsedInCtor; + + template.save(source); + + DocumentWithLazyDBrefUsedInPresistenceConstructor loaded = template.findOne(query(where("id").is(source.id)), + DocumentWithLazyDBrefUsedInPresistenceConstructor.class); + assertThat(loaded.refToDocNotUsedInCtor, instanceOf(LazyLoadingProxy.class)); + assertThat(loaded.refToDocUsedInCtor, nullValue()); + } + + /** + * @see DATAMONGO-1287 + */ + @Test + public void shouldRespectParamterValueWhenAttemptingToReuseLazyLoadedDBRefUsedInPersistenceConstrcutor() { + + Document docInCtor = new Document(); + docInCtor.id = "doc-in-ctor"; + template.save(docInCtor); + + Document docNotUsedInCtor = new Document(); + docNotUsedInCtor.id = "doc-but-not-used-in-ctor"; + template.save(docNotUsedInCtor); + + DocumentWithLazyDBrefUsedInPresistenceConstructor source = new DocumentWithLazyDBrefUsedInPresistenceConstructor( + docInCtor); + source.refToDocNotUsedInCtor = docNotUsedInCtor; + + template.save(source); + + DocumentWithLazyDBrefUsedInPresistenceConstructor loaded = template.findOne(query(where("id").is(source.id)), + DocumentWithLazyDBrefUsedInPresistenceConstructor.class); + assertThat(loaded.refToDocUsedInCtor, not(instanceOf(LazyLoadingProxy.class))); + assertThat(loaded.refToDocNotUsedInCtor, instanceOf(LazyLoadingProxy.class)); + } + static class DoucmentWithNamedIdField { @Id String someIdKey; @@ -3401,4 +3470,18 @@ public class MongoTemplateTests { @org.springframework.data.mongodb.core.mapping.DBRef SomeContent dbrefContent; SomeContent normalContent; } + + static class DocumentWithLazyDBrefUsedInPresistenceConstructor { + + @Id String id; + @org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) Document refToDocUsedInCtor; + @org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) Document refToDocNotUsedInCtor; + + @PersistenceConstructor + public DocumentWithLazyDBrefUsedInPresistenceConstructor(Document refToDocUsedInCtor) { + this.refToDocUsedInCtor = refToDocUsedInCtor; + } + + } + }