From b0eb0c47d24dbf96b4ecad7f50589bfdc11ec57b Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Fri, 17 Aug 2018 11:46:14 +0200 Subject: [PATCH] DATACMNS-1377 - ConvertingPropertyAccessor now properly coverts values for property paths. Previously, ConvertingPropertyAccessor did not override PersistentPropertyAccessor.setProperty(PersistentPropertyPath, Object), so that the target value had to be of the leaf property's type. We now implement that method and convert it into that type before invoking the super method. --- .../model/ConvertingPropertyAccessor.java | 13 +++++++++++++ .../PersistentPropertyAccessorUnitTests.java | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/main/java/org/springframework/data/mapping/model/ConvertingPropertyAccessor.java b/src/main/java/org/springframework/data/mapping/model/ConvertingPropertyAccessor.java index 7dd6b27b6..0c6d2f4ee 100644 --- a/src/main/java/org/springframework/data/mapping/model/ConvertingPropertyAccessor.java +++ b/src/main/java/org/springframework/data/mapping/model/ConvertingPropertyAccessor.java @@ -18,6 +18,7 @@ package org.springframework.data.mapping.model; import org.springframework.core.convert.ConversionService; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; +import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -60,6 +61,18 @@ public class ConvertingPropertyAccessor implements PersistentPropertyAccessor accessor.setProperty(property, convertIfNecessary(value, property.getType())); } + /* + * (non-Javadoc) + * @see org.springframework.data.mapping.PersistentPropertyAccessor#setProperty(org.springframework.data.mapping.PersistentPropertyPath, java.lang.Object) + */ + @Override + public void setProperty(PersistentPropertyPath> path, @Nullable Object value) { + + Object converted = convertIfNecessary(value, path.getRequiredLeafProperty().getType()); + + PersistentPropertyAccessor.super.setProperty(path, converted); + } + /* * (non-Javadoc) * @see org.springframework.data.mapping.PersistentPropertyAccessor#getProperty(org.springframework.data.mapping.PersistentProperty) diff --git a/src/test/java/org/springframework/data/mapping/PersistentPropertyAccessorUnitTests.java b/src/test/java/org/springframework/data/mapping/PersistentPropertyAccessorUnitTests.java index f426ed4f3..2ffc80cdb 100644 --- a/src/test/java/org/springframework/data/mapping/PersistentPropertyAccessorUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/PersistentPropertyAccessorUnitTests.java @@ -24,8 +24,10 @@ import lombok.Value; import lombok.experimental.Wither; import org.junit.Test; +import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.mapping.context.SampleMappingContext; import org.springframework.data.mapping.context.SamplePersistentProperty; +import org.springframework.data.mapping.model.ConvertingPropertyAccessor; /** * @author Oliver Gierke @@ -114,6 +116,23 @@ public class PersistentPropertyAccessorUnitTests { }); } + @Test // DATACMNS-1377 + public void shouldConvertToPropertyPathLeafType() { + + Order order = new Order(new Customer("1")); + + PersistentPropertyAccessor accessor = context.getPersistentEntity(Order.class).getPropertyAccessor(order); + ConvertingPropertyAccessor convertingAccessor = new ConvertingPropertyAccessor<>(accessor, + new DefaultConversionService()); + + PersistentPropertyPath path = context.getPersistentPropertyPath("customer.firstname", + Order.class); + + convertingAccessor.setProperty(path, 2); + + assertThat(convertingAccessor.getBean().getCustomer().getFirstname()).isEqualTo("2"); + } + @Value static class Order { Customer customer;