DATACMNS-1296 - PersistentPropertyPathAccessor now properly handles intermediate nulls when setting values.
We now use a dedicated GetOptions instance for the lookup of the parent path in case SetOptions is defined to skip nulls so that the lookup does not fail if the parent path contains a null value.
This commit is contained in:
@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
|
||||
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;
|
||||
@@ -53,6 +54,8 @@ import org.springframework.util.Assert;
|
||||
@RequiredArgsConstructor
|
||||
class SimplePersistentPropertyPathAccessor<T> implements PersistentPropertyPathAccessor<T> {
|
||||
|
||||
private static final GetOptions DEFAULT_GET_OPTIONS = AccessOptions.defaultGetOptions();
|
||||
|
||||
private final @NonNull PersistentPropertyAccessor<T> delegate;
|
||||
|
||||
/*
|
||||
@@ -81,7 +84,7 @@ class SimplePersistentPropertyPathAccessor<T> implements PersistentPropertyPathA
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getProperty(PersistentPropertyPath<? extends PersistentProperty<?>> path) {
|
||||
return getProperty(path, AccessOptions.defaultGetOptions());
|
||||
return getProperty(path, DEFAULT_GET_OPTIONS);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -151,7 +154,11 @@ class SimplePersistentPropertyPathAccessor<T> 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());
|
||||
|
||||
@@ -86,6 +86,20 @@ class SimplePersistentPropertyPathAccessorUnitTests {
|
||||
}).doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1296
|
||||
void skipsIntermediateNullsWhenSettingNestedValues() {
|
||||
|
||||
CustomerWrapperWrapper wrapper = new CustomerWrapperWrapper(null);
|
||||
|
||||
PersistentPropertyPathAccessor<CustomerWrapperWrapper> accessor = getAccessor(wrapper);
|
||||
PersistentPropertyPath<SamplePersistentProperty> 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<SamplePersistentProperty> propertyPath = context.getPersistentPropertyPath(path,
|
||||
@@ -124,4 +138,9 @@ class SimplePersistentPropertyPathAccessorUnitTests {
|
||||
static class CustomerWrapper {
|
||||
Customer customer;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
static class CustomerWrapperWrapper {
|
||||
CustomerWrapper wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user