diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java index 03e5eb0d5..89d7360e4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentReferenceSource.java @@ -28,11 +28,11 @@ public class DocumentReferenceSource { private final Object self; - @Nullable private final Object targetSource; + private final @Nullable Object targetSource; /** * Create a new instance of {@link DocumentReferenceSource}. - * + * * @param self the entire wrapper object holding references. Must not be {@literal null}. * @param targetSource the reference value source. */ @@ -60,4 +60,25 @@ public class DocumentReferenceSource { public Object getTargetSource() { return targetSource; } + + /** + * Dereference a {@code targetSource} if it is a {@link DocumentReferenceSource} or return {@code source} otherwise. + * + * @param source + * @return + */ + @Nullable + static Object getTargetSource(Object source) { + return source instanceof DocumentReferenceSource ? ((DocumentReferenceSource) source).getTargetSource() : source; + } + + /** + * Dereference a {@code self} object if it is a {@link DocumentReferenceSource} or return {@code self} otherwise. + * + * @param self + * @return + */ + static Object getSelf(Object self) { + return self instanceof DocumentReferenceSource ? ((DocumentReferenceSource) self).getSelf() : self; + } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java index e16f9024b..36ccc23a6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReferenceLookupDelegate.java @@ -174,7 +174,6 @@ public final class ReferenceLookupDelegate { * @param * @return can be {@literal null}. */ - @Nullable @SuppressWarnings("unchecked") private T parseValueOrGet(String value, ParameterBindingContext bindingContext, Supplier defaultValue) { @@ -199,16 +198,10 @@ public final class ReferenceLookupDelegate { ParameterBindingContext bindingContext(MongoPersistentProperty property, Object source, SpELContext spELContext) { - ValueProvider valueProvider; - if (source instanceof DocumentReferenceSource) { - valueProvider = valueProviderFor(((DocumentReferenceSource) source).getTargetSource()); - } else { - valueProvider = valueProviderFor(source); - } + ValueProvider valueProvider = valueProviderFor(DocumentReferenceSource.getTargetSource(source)); return new ParameterBindingContext(valueProvider, spELContext.getParser(), () -> evaluationContextFor(property, source, spELContext)); - } ValueProvider valueProviderFor(Object source) { @@ -232,8 +225,7 @@ public final class ReferenceLookupDelegate { EvaluationContext ctx = spELContext.getEvaluationContext(target); ctx.setVariable("target", target); - ctx.setVariable("self", - source instanceof DocumentReferenceSource ? ((DocumentReferenceSource) source).getSelf() : source); + ctx.setVariable("self", DocumentReferenceSource.getSelf(source)); ctx.setVariable(property.getName(), target); return ctx; @@ -255,11 +247,10 @@ public final class ReferenceLookupDelegate { String lookup = documentReference.lookup(); - Object value = source instanceof DocumentReferenceSource ? ((DocumentReferenceSource) source).getTargetSource() - : source; + Object value = DocumentReferenceSource.getTargetSource(source); Document sort = parseValueOrGet(documentReference.sort(), bindingContext(property, source, spELContext), - () -> new Document()); + Document::new); if (property.isCollectionLike() && (value instanceof Collection || value == null)) { diff --git a/src/main/asciidoc/reference/document-references.adoc b/src/main/asciidoc/reference/document-references.adoc index 23bc025e8..b7d55678a 100644 --- a/src/main/asciidoc/reference/document-references.adoc +++ b/src/main/asciidoc/reference/document-references.adoc @@ -263,7 +263,7 @@ class Publisher { ==== It is also possible to model relational style _One-To-Many_ references using a combination of `@ReadonlyProperty` and `@DocumentReference`. -This approach allows to link types without explicitly storing the linking values within the document itself as shown in the snipped below. +This approach allows link types without storing the linking values within the owning document but rather on the referencing document as shown in the example below. ==== [source,java] @@ -313,8 +313,9 @@ class Publisher { "name" : "Del Rey" } ---- -<1> Set up the link from `Book` to `Publisher` by storing the `Publisher.id` within the `Book` document. -<2> Mark the property holding the references to be read only. This prevents storing references to individual ``Book``s with the `Publisher` document. +<1> Set up the link from `Book` (reference) to `Publisher` (owner) by storing the `Publisher.id` within the `Book` document. +<2> Mark the property holding the references to be readonly. +This prevents storing references to individual ``Book``s with the `Publisher` document. <3> Use the `#self` variable to access values within the `Publisher` document and in this retrieve `Books` with matching `publisherId`. ====