DATAMONGO-1287 - Fix double fetching for lazy DbRefs used in entity constructor.
We now check properties for their usage as constructor arguments, that might already have been resolved, before setting the actual value. This prevents turning already eagerly fetched DBRefs back into LazyLoadingProxies. Original pull request: #335. Related pull request: #322.
This commit is contained in:
committed by
Oliver Gierke
parent
e30eeaae79
commit
0cc050e966
@@ -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<MongoPersistentProperty>() {
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user