diff --git a/src/main/java/org/springframework/data/mapping/model/SimplePersistentPropertyPathAccessor.java b/src/main/java/org/springframework/data/mapping/model/SimplePersistentPropertyPathAccessor.java index 07c6abb10..3a25cd4b9 100644 --- a/src/main/java/org/springframework/data/mapping/model/SimplePersistentPropertyPathAccessor.java +++ b/src/main/java/org/springframework/data/mapping/model/SimplePersistentPropertyPathAccessor.java @@ -24,10 +24,10 @@ import java.util.stream.Collectors; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.core.CollectionFactory; import org.springframework.data.mapping.AccessOptions; import org.springframework.data.mapping.AccessOptions.GetOptions; +import org.springframework.data.mapping.AccessOptions.GetOptions.GetNulls; import org.springframework.data.mapping.AccessOptions.SetOptions; import org.springframework.data.mapping.AccessOptions.SetOptions.SetNulls; import org.springframework.data.mapping.MappingException; @@ -51,6 +51,7 @@ import org.springframework.util.Assert; class SimplePersistentPropertyPathAccessor implements PersistentPropertyPathAccessor { private static final Log logger = LogFactory.getLog(SimplePersistentPropertyPathAccessor.class); + private static final GetOptions DEFAULT_GET_OPTIONS = AccessOptions.defaultGetOptions(); private final PersistentPropertyAccessor delegate; @@ -84,7 +85,7 @@ class SimplePersistentPropertyPathAccessor implements PersistentPropertyPathA @Nullable @Override public Object getProperty(PersistentPropertyPath> path) { - return getProperty(path, AccessOptions.defaultGetOptions()); + return getProperty(path, DEFAULT_GET_OPTIONS); } /* @@ -154,7 +155,11 @@ class SimplePersistentPropertyPathAccessor implements PersistentPropertyPathA return; } - Object parent = parentPath.isEmpty() ? getBean() : getProperty(parentPath); + GetOptions lookupOptions = options.getNullHandling() != REJECT + ? DEFAULT_GET_OPTIONS.withNullValues(GetNulls.EARLY_RETURN) + : DEFAULT_GET_OPTIONS; + + Object parent = parentPath.isEmpty() ? getBean() : getProperty(parentPath, lookupOptions); if (parent == null) { handleNull(path, options.getNullHandling()); diff --git a/src/test/java/org/springframework/data/mapping/model/SimplePersistentPropertyPathAccessorUnitTests.java b/src/test/java/org/springframework/data/mapping/model/SimplePersistentPropertyPathAccessorUnitTests.java index 6e7b78043..ab1ab395a 100644 --- a/src/test/java/org/springframework/data/mapping/model/SimplePersistentPropertyPathAccessorUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/SimplePersistentPropertyPathAccessorUnitTests.java @@ -86,6 +86,20 @@ class SimplePersistentPropertyPathAccessorUnitTests { }).doesNotThrowAnyException(); } + @Test // DATACMNS-1296 + void skipsIntermediateNullsWhenSettingNestedValues() { + + CustomerWrapperWrapper wrapper = new CustomerWrapperWrapper(null); + + PersistentPropertyPathAccessor accessor = getAccessor(wrapper); + PersistentPropertyPath path = context + .getPersistentPropertyPath("wrapper.customer.firstname", CustomerWrapperWrapper.class); + + assertThatCode(() -> { + accessor.setProperty(path, "Dave", AccessOptions.defaultSetOptions().skipNulls()); + }).doesNotThrowAnyException(); + } + private void assertFirstnamesSetFor(Customers customers, String path) { PersistentPropertyPath propertyPath = context.getPersistentPropertyPath(path, @@ -124,4 +138,9 @@ class SimplePersistentPropertyPathAccessorUnitTests { static class CustomerWrapper { Customer customer; } + + @AllArgsConstructor + static class CustomerWrapperWrapper { + CustomerWrapper wrapper; + } }