Skip to content

Commit d759f5d

Browse files
mp911dechristophstrobl
authored andcommitted
Consistently use the same reading strategies to read associations.
Return the value to set instead of calling the accessor directly. Remove duplicate calls to resolve associations. See #4491
1 parent 531d3ac commit d759f5d

File tree

1 file changed

+28
-46
lines changed

1 file changed

+28
-46
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java

+28-46
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,6 @@ private <S> S read(ConversionContext context, MongoPersistentEntity<S> entity, D
510510
S instance = instantiator.createInstance(entity, provider);
511511

512512
if (entity.requiresPropertyPopulation()) {
513-
514513
return populateProperties(context, entity, documentAccessor, evaluator, instance);
515514
}
516515

@@ -589,14 +588,18 @@ private void readProperties(ConversionContext context, MongoPersistentEntity<?>
589588
ConversionContext propertyContext = context.forProperty(prop);
590589
MongoDbPropertyValueProvider valueProviderToUse = valueProvider.withContext(propertyContext);
591590

592-
if (prop.isAssociation() && !entity.isCreatorArgument(prop)) {
591+
if (prop.isAssociation()) {
593592

594593
if (callback == null) {
595594
callback = getDbRefResolverCallback(propertyContext, documentAccessor, evaluator);
596595
}
597596

598-
readAssociation(prop.getRequiredAssociation(), accessor, documentAccessor, dbRefProxyHandler, callback,
599-
propertyContext, evaluator);
597+
Object value = readAssociation(prop.getRequiredAssociation(), documentAccessor, dbRefProxyHandler, callback,
598+
propertyContext);
599+
600+
if (value != null) {
601+
accessor.setProperty(prop, value);
602+
}
600603
continue;
601604
}
602605

@@ -611,17 +614,6 @@ private void readProperties(ConversionContext context, MongoPersistentEntity<?>
611614
continue;
612615
}
613616

614-
if (prop.isAssociation()) {
615-
616-
if (callback == null) {
617-
callback = getDbRefResolverCallback(propertyContext, documentAccessor, evaluator);
618-
}
619-
620-
readAssociation(prop.getRequiredAssociation(), accessor, documentAccessor, dbRefProxyHandler, callback,
621-
propertyContext, evaluator);
622-
continue;
623-
}
624-
625617
accessor.setProperty(prop, valueProviderToUse.getPropertyValue(prop));
626618
}
627619
}
@@ -633,9 +625,10 @@ private DbRefResolverCallback getDbRefResolverCallback(ConversionContext context
633625
(prop, bson, e, path) -> MappingMongoConverter.this.getValueInternal(context, prop, bson, e));
634626
}
635627

636-
private void readAssociation(Association<MongoPersistentProperty> association, PersistentPropertyAccessor<?> accessor,
628+
@Nullable
629+
private Object readAssociation(Association<MongoPersistentProperty> association,
637630
DocumentAccessor documentAccessor, DbRefProxyHandler handler, DbRefResolverCallback callback,
638-
ConversionContext context, SpELExpressionEvaluator evaluator) {
631+
ConversionContext context) {
639632

640633
MongoPersistentProperty property = association.getInverse();
641634
Object value = documentAccessor.get(property);
@@ -648,30 +641,27 @@ private void readAssociation(Association<MongoPersistentProperty> association, P
648641
if (conversionService.canConvert(DocumentPointer.class, property.getActualType())) {
649642

650643
if (value == null) {
651-
return;
644+
return null;
652645
}
653646

654647
DocumentPointer<?> pointer = () -> value;
655648

656649
// collection like special treatment
657-
accessor.setProperty(property, conversionService.convert(pointer, property.getActualType()));
650+
return conversionService.convert(pointer, property.getActualType());
658651
} else {
659652

660-
accessor.setProperty(property,
661-
dbRefResolver.resolveReference(property,
653+
return dbRefResolver.resolveReference(property,
662654
new DocumentReferenceSource(documentAccessor.getDocument(), documentAccessor.get(property)),
663-
referenceLookupDelegate, context.forProperty(property)::convert));
655+
referenceLookupDelegate, context.forProperty(property)::convert);
664656
}
665-
return;
666657
}
667658

668659
if (value == null) {
669-
return;
660+
return null;
670661
}
671662

672663
if (value instanceof DBRef dbref) {
673-
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, dbref, callback, handler));
674-
return;
664+
return dbRefResolver.resolveDbRef(property, dbref, callback, handler);
675665
}
676666

677667
/*
@@ -682,18 +672,18 @@ private void readAssociation(Association<MongoPersistentProperty> association, P
682672
if (value instanceof Document document) {
683673
if (property.isMap()) {
684674
if (document.isEmpty() || peek(document.values()) instanceof DBRef) {
685-
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, null, callback, handler));
675+
return dbRefResolver.resolveDbRef(property, null, callback, handler);
686676
} else {
687-
accessor.setProperty(property, readMap(context, document, property.getTypeInformation()));
677+
return readMap(context, document, property.getTypeInformation());
688678
}
689679
} else {
690-
accessor.setProperty(property, read(property.getActualType(), document));
680+
return read(property.getActualType(), document);
691681
}
692682
} else if (value instanceof Collection<?> collection && !collection.isEmpty()
693683
&& peek(collection) instanceof Document) {
694-
accessor.setProperty(property, readCollectionOrArray(context, collection, property.getTypeInformation()));
684+
return readCollectionOrArray(context, collection, property.getTypeInformation());
695685
} else {
696-
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, null, callback, handler));
686+
return dbRefResolver.resolveDbRef(property, null, callback, handler);
697687
}
698688
}
699689

@@ -1965,26 +1955,14 @@ public <T> T getPropertyValue(MongoPersistentProperty property) {
19651955

19661956
ConversionContext propertyContext = context.forProperty(property);
19671957

1968-
if (property.isDbReference() && property.getDBRef().lazy()) {
1969-
1970-
Object rawRefValue = accessor.get(property);
1971-
if (rawRefValue == null) {
1972-
return null;
1973-
}
1958+
if (property.isAssociation()) {
19741959

19751960
DbRefResolverCallback callback = new DefaultDbRefResolverCallback(accessor.getDocument(), context.getPath(),
19761961
evaluator, (prop, bson, evaluator, path) -> MappingMongoConverter.this.getValueInternal(context, prop, bson,
19771962
evaluator));
19781963

1979-
DBRef dbref = rawRefValue instanceof DBRef ? (DBRef) rawRefValue : null;
1980-
return (T) dbRefResolver.resolveDbRef(property, dbref, callback, dbRefProxyHandler);
1981-
}
1982-
1983-
if (property.isDocumentReference()) {
1984-
1985-
return (T) dbRefResolver.resolveReference(property,
1986-
new DocumentReferenceSource(accessor.getDocument(), accessor.get(property)), referenceLookupDelegate,
1987-
context::convert);
1964+
return (T) readAssociation(property.getRequiredAssociation(), accessor, dbRefProxyHandler, callback,
1965+
propertyContext);
19881966
}
19891967

19901968
if (property.isUnwrapped()) {
@@ -1993,6 +1971,10 @@ public <T> T getPropertyValue(MongoPersistentProperty property) {
19931971
mappingContext.getRequiredPersistentEntity(property));
19941972
}
19951973

1974+
if (!accessor.hasValue(property)) {
1975+
return null;
1976+
}
1977+
19961978
return super.getPropertyValue(property);
19971979
}
19981980
}

0 commit comments

Comments
 (0)