From ce1339549faae90899cf16f8b61f06303484b060 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 19 Nov 2015 11:43:24 +0100 Subject: [PATCH 1/2] DATAMONGO-1287 - MappingMongoConverter eagerly fetches and converts lazy DbRef to change them afterwards by proxies. Prepare issue branch. --- pom.xml | 2 +- spring-data-mongodb-cross-store/pom.xml | 4 ++-- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb-log4j/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 41512eaee8..39178d1b94 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 1.9.0.BUILD-SNAPSHOT + 1.9.0.DATAMONGO-1287-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-cross-store/pom.xml b/spring-data-mongodb-cross-store/pom.xml index fd36debedd..dd1c8da214 100644 --- a/spring-data-mongodb-cross-store/pom.xml +++ b/spring-data-mongodb-cross-store/pom.xml @@ -6,7 +6,7 @@ org.springframework.data spring-data-mongodb-parent - 1.9.0.BUILD-SNAPSHOT + 1.9.0.DATAMONGO-1287-SNAPSHOT ../pom.xml @@ -48,7 +48,7 @@ org.springframework.data spring-data-mongodb - 1.9.0.BUILD-SNAPSHOT + 1.9.0.DATAMONGO-1287-SNAPSHOT diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index 28c91bc332..36a307a391 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -13,7 +13,7 @@ org.springframework.data spring-data-mongodb-parent - 1.9.0.BUILD-SNAPSHOT + 1.9.0.DATAMONGO-1287-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb-log4j/pom.xml b/spring-data-mongodb-log4j/pom.xml index dfe146ff96..b599e28cf0 100644 --- a/spring-data-mongodb-log4j/pom.xml +++ b/spring-data-mongodb-log4j/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 1.9.0.BUILD-SNAPSHOT + 1.9.0.DATAMONGO-1287-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 0fcdb2f39f..ca65b7d355 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -11,7 +11,7 @@ org.springframework.data spring-data-mongodb-parent - 1.9.0.BUILD-SNAPSHOT + 1.9.0.DATAMONGO-1287-SNAPSHOT ../pom.xml From 4305fbccd3b496f4c0741ec0e99b2a29d09fad81 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 19 Nov 2015 14:10:17 +0100 Subject: [PATCH 2/2] DATAMONGO-1287 - Fix double fetching for lazy DbRef used in ctor. We now check properties for their usage as ctor arguments, that might already have been resolved, before setting the actual value. This prevents turning already eagerly fetched DBRefs back into LazyLoadingProxies. Relates to original PR #322. --- .../core/convert/MappingMongoConverter.java | 4 +- .../data/mongodb/core/MongoTemplateTests.java | 86 ++++++++++++++++++- 2 files changed, 88 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 7775767dc5..ae6c49077f 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 @@ -290,7 +290,9 @@ public void doWithAssociation(Association association) final MongoPersistentProperty property = association.getInverse(); Object value = dbo.get(property.getFieldName()); - if (value == null) { + if (value == null + || (entity.getPersistenceConstructor().hasParameters() && 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 914d4bd4cf..aad76ace25 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 @@ -197,6 +197,7 @@ protected void cleanDb() { template.dropCollection(SomeTemplate.class); template.dropCollection(Address.class); template.dropCollection(DocumentWithCollectionOfSamples.class); + template.dropCollection(DocumentWithLazyDBrefUsedInPresistenceConstructor.class); } @Test @@ -3035,7 +3036,7 @@ public void takesSortIntoAccountWhenStreaming() { */ @Test public void takesLimitIntoAccountWhenStreaming() { - + Person youngestPerson = new Person("John", 20); Person oldestPerson = new Person("Jane", 42); @@ -3049,6 +3050,75 @@ public void takesLimitIntoAccountWhenStreaming() { assertThat(stream.hasNext(), is(false)); } + /** + * @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; @@ -3375,4 +3445,18 @@ static class SomeMessage { @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; + } + + } + }