Skip to content

Commit 7213b99

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 04e80ed commit 7213b99

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
@@ -507,7 +507,6 @@ private <S> S read(ConversionContext context, MongoPersistentEntity<S> entity, D
507507
S instance = instantiator.createInstance(entity, provider);
508508

509509
if (entity.requiresPropertyPopulation()) {
510-
511510
return populateProperties(context, entity, documentAccessor, evaluator, instance);
512511
}
513512

@@ -586,14 +585,18 @@ private void readProperties(ConversionContext context, MongoPersistentEntity<?>
586585
ConversionContext propertyContext = context.forProperty(prop);
587586
MongoDbPropertyValueProvider valueProviderToUse = valueProvider.withContext(propertyContext);
588587

589-
if (prop.isAssociation() && !entity.isCreatorArgument(prop)) {
588+
if (prop.isAssociation()) {
590589

591590
if (callback == null) {
592591
callback = getDbRefResolverCallback(propertyContext, documentAccessor, evaluator);
593592
}
594593

595-
readAssociation(prop.getRequiredAssociation(), accessor, documentAccessor, dbRefProxyHandler, callback,
596-
propertyContext, evaluator);
594+
Object value = readAssociation(prop.getRequiredAssociation(), documentAccessor, dbRefProxyHandler, callback,
595+
propertyContext);
596+
597+
if (value != null) {
598+
accessor.setProperty(prop, value);
599+
}
597600
continue;
598601
}
599602

@@ -608,17 +611,6 @@ private void readProperties(ConversionContext context, MongoPersistentEntity<?>
608611
continue;
609612
}
610613

611-
if (prop.isAssociation()) {
612-
613-
if (callback == null) {
614-
callback = getDbRefResolverCallback(propertyContext, documentAccessor, evaluator);
615-
}
616-
617-
readAssociation(prop.getRequiredAssociation(), accessor, documentAccessor, dbRefProxyHandler, callback,
618-
propertyContext, evaluator);
619-
continue;
620-
}
621-
622614
accessor.setProperty(prop, valueProviderToUse.getPropertyValue(prop));
623615
}
624616
}
@@ -630,9 +622,10 @@ private DbRefResolverCallback getDbRefResolverCallback(ConversionContext context
630622
(prop, bson, e, path) -> MappingMongoConverter.this.getValueInternal(context, prop, bson, e));
631623
}
632624

633-
private void readAssociation(Association<MongoPersistentProperty> association, PersistentPropertyAccessor<?> accessor,
625+
@Nullable
626+
private Object readAssociation(Association<MongoPersistentProperty> association,
634627
DocumentAccessor documentAccessor, DbRefProxyHandler handler, DbRefResolverCallback callback,
635-
ConversionContext context, SpELExpressionEvaluator evaluator) {
628+
ConversionContext context) {
636629

637630
MongoPersistentProperty property = association.getInverse();
638631
Object value = documentAccessor.get(property);
@@ -645,30 +638,27 @@ private void readAssociation(Association<MongoPersistentProperty> association, P
645638
if (conversionService.canConvert(DocumentPointer.class, property.getActualType())) {
646639

647640
if (value == null) {
648-
return;
641+
return null;
649642
}
650643

651644
DocumentPointer<?> pointer = () -> value;
652645

653646
// collection like special treatment
654-
accessor.setProperty(property, conversionService.convert(pointer, property.getActualType()));
647+
return conversionService.convert(pointer, property.getActualType());
655648
} else {
656649

657-
accessor.setProperty(property,
658-
dbRefResolver.resolveReference(property,
650+
return dbRefResolver.resolveReference(property,
659651
new DocumentReferenceSource(documentAccessor.getDocument(), documentAccessor.get(property)),
660-
referenceLookupDelegate, context.forProperty(property)::convert));
652+
referenceLookupDelegate, context.forProperty(property)::convert);
661653
}
662-
return;
663654
}
664655

665656
if (value == null) {
666-
return;
657+
return null;
667658
}
668659

669660
if (value instanceof DBRef dbref) {
670-
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, dbref, callback, handler));
671-
return;
661+
return dbRefResolver.resolveDbRef(property, dbref, callback, handler);
672662
}
673663

674664
/*
@@ -679,18 +669,18 @@ private void readAssociation(Association<MongoPersistentProperty> association, P
679669
if (value instanceof Document document) {
680670
if (property.isMap()) {
681671
if (document.isEmpty() || peek(document.values()) instanceof DBRef) {
682-
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, null, callback, handler));
672+
return dbRefResolver.resolveDbRef(property, null, callback, handler);
683673
} else {
684-
accessor.setProperty(property, readMap(context, document, property.getTypeInformation()));
674+
return readMap(context, document, property.getTypeInformation());
685675
}
686676
} else {
687-
accessor.setProperty(property, read(property.getActualType(), document));
677+
return read(property.getActualType(), document);
688678
}
689679
} else if (value instanceof Collection<?> collection && !collection.isEmpty()
690680
&& peek(collection) instanceof Document) {
691-
accessor.setProperty(property, readCollectionOrArray(context, collection, property.getTypeInformation()));
681+
return readCollectionOrArray(context, collection, property.getTypeInformation());
692682
} else {
693-
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, null, callback, handler));
683+
return dbRefResolver.resolveDbRef(property, null, callback, handler);
694684
}
695685
}
696686

@@ -1978,26 +1968,14 @@ public <T> T getPropertyValue(MongoPersistentProperty property) {
19781968

19791969
ConversionContext propertyContext = context.forProperty(property);
19801970

1981-
if (property.isDbReference() && property.getDBRef().lazy()) {
1982-
1983-
Object rawRefValue = accessor.get(property);
1984-
if (rawRefValue == null) {
1985-
return null;
1986-
}
1971+
if (property.isAssociation()) {
19871972

19881973
DbRefResolverCallback callback = new DefaultDbRefResolverCallback(accessor.getDocument(), context.getPath(),
19891974
evaluator, (prop, bson, evaluator, path) -> MappingMongoConverter.this.getValueInternal(context, prop, bson,
19901975
evaluator));
19911976

1992-
DBRef dbref = rawRefValue instanceof DBRef dbRef ? dbRef : null;
1993-
return (T) dbRefResolver.resolveDbRef(property, dbref, callback, dbRefProxyHandler);
1994-
}
1995-
1996-
if (property.isDocumentReference()) {
1997-
1998-
return (T) dbRefResolver.resolveReference(property,
1999-
new DocumentReferenceSource(accessor.getDocument(), accessor.get(property)), referenceLookupDelegate,
2000-
context::convert);
1977+
return (T) readAssociation(property.getRequiredAssociation(), accessor, dbRefProxyHandler, callback,
1978+
propertyContext);
20011979
}
20021980

20031981
if (property.isUnwrapped()) {
@@ -2006,6 +1984,10 @@ public <T> T getPropertyValue(MongoPersistentProperty property) {
20061984
mappingContext.getRequiredPersistentEntity(property));
20071985
}
20081986

1987+
if (!accessor.hasValue(property)) {
1988+
return null;
1989+
}
1990+
20091991
return super.getPropertyValue(property);
20101992
}
20111993
}

0 commit comments

Comments
 (0)