Skip to content

Commit

Permalink
Consistently use the same reading strategies to read associations.
Browse files Browse the repository at this point in the history
Return the value to set instead of calling the accessor directly. Remove duplicate calls to resolve associations.

See #4491
  • Loading branch information
mp911de authored and christophstrobl committed Sep 11, 2023
1 parent b2809d6 commit 69c9e0f
Showing 1 changed file with 28 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,6 @@ private <S> S read(ConversionContext context, MongoPersistentEntity<S> entity, D
S instance = instantiator.createInstance(entity, provider);

if (entity.requiresPropertyPopulation()) {

return populateProperties(context, entity, documentAccessor, evaluator, instance);
}

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

if (prop.isAssociation() && !entity.isCreatorArgument(prop)) {
if (prop.isAssociation()) {

if (callback == null) {
callback = getDbRefResolverCallback(propertyContext, documentAccessor, evaluator);
}

readAssociation(prop.getRequiredAssociation(), accessor, documentAccessor, dbRefProxyHandler, callback,
propertyContext, evaluator);
Object value = readAssociation(prop.getRequiredAssociation(), documentAccessor, dbRefProxyHandler, callback,
propertyContext);

if (value != null) {
accessor.setProperty(prop, value);
}
continue;
}

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

if (prop.isAssociation()) {

if (callback == null) {
callback = getDbRefResolverCallback(propertyContext, documentAccessor, evaluator);
}

readAssociation(prop.getRequiredAssociation(), accessor, documentAccessor, dbRefProxyHandler, callback,
propertyContext, evaluator);
continue;
}

accessor.setProperty(prop, valueProviderToUse.getPropertyValue(prop));
}
}
Expand All @@ -630,9 +622,10 @@ private DbRefResolverCallback getDbRefResolverCallback(ConversionContext context
(prop, bson, e, path) -> MappingMongoConverter.this.getValueInternal(context, prop, bson, e));
}

private void readAssociation(Association<MongoPersistentProperty> association, PersistentPropertyAccessor<?> accessor,
@Nullable
private Object readAssociation(Association<MongoPersistentProperty> association,
DocumentAccessor documentAccessor, DbRefProxyHandler handler, DbRefResolverCallback callback,
ConversionContext context, SpELExpressionEvaluator evaluator) {
ConversionContext context) {

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

if (value == null) {
return;
return null;
}

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

// collection like special treatment
accessor.setProperty(property, conversionService.convert(pointer, property.getActualType()));
return conversionService.convert(pointer, property.getActualType());
} else {

accessor.setProperty(property,
dbRefResolver.resolveReference(property,
return dbRefResolver.resolveReference(property,
new DocumentReferenceSource(documentAccessor.getDocument(), documentAccessor.get(property)),
referenceLookupDelegate, context.forProperty(property)::convert));
referenceLookupDelegate, context.forProperty(property)::convert);
}
return;
}

if (value == null) {
return;
return null;
}

if (value instanceof DBRef dbref) {
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, dbref, callback, handler));
return;
return dbRefResolver.resolveDbRef(property, dbref, callback, handler);
}

/*
Expand All @@ -679,18 +669,18 @@ private void readAssociation(Association<MongoPersistentProperty> association, P
if (value instanceof Document document) {
if (property.isMap()) {
if (document.isEmpty() || peek(document.values()) instanceof DBRef) {
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, null, callback, handler));
return dbRefResolver.resolveDbRef(property, null, callback, handler);
} else {
accessor.setProperty(property, readMap(context, document, property.getTypeInformation()));
return readMap(context, document, property.getTypeInformation());
}
} else {
accessor.setProperty(property, read(property.getActualType(), document));
return read(property.getActualType(), document);
}
} else if (value instanceof Collection<?> collection && !collection.isEmpty()
&& peek(collection) instanceof Document) {
accessor.setProperty(property, readCollectionOrArray(context, collection, property.getTypeInformation()));
return readCollectionOrArray(context, collection, property.getTypeInformation());
} else {
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, null, callback, handler));
return dbRefResolver.resolveDbRef(property, null, callback, handler);
}
}

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

ConversionContext propertyContext = context.forProperty(property);

if (property.isDbReference() && property.getDBRef().lazy()) {

Object rawRefValue = accessor.get(property);
if (rawRefValue == null) {
return null;
}
if (property.isAssociation()) {

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

DBRef dbref = rawRefValue instanceof DBRef dbRef ? dbRef : null;
return (T) dbRefResolver.resolveDbRef(property, dbref, callback, dbRefProxyHandler);
}

if (property.isDocumentReference()) {

return (T) dbRefResolver.resolveReference(property,
new DocumentReferenceSource(accessor.getDocument(), accessor.get(property)), referenceLookupDelegate,
context::convert);
return (T) readAssociation(property.getRequiredAssociation(), accessor, dbRefProxyHandler, callback,
propertyContext);
}

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

if (!accessor.hasValue(property)) {
return null;
}

return super.getPropertyValue(property);
}
}
Expand Down

0 comments on commit 69c9e0f

Please sign in to comment.