Add JSR310 converters to the converters used for projections.

Similar converters where removed because they clashed with the support for nullable wrappers. This adds them back as dedicated converters that does not clash with conversions for nullable wrappers.

See bd3992dfc5 (diff-96f7084777a2a702d85f5c600e542b10123d6c3332ed3d3f8e329ca7061faab0R55)

Original Pull Request: #479
Closes: #2223
This commit is contained in:
Jens Schauder
2020-12-07 15:10:03 +01:00
committed by Christoph Strobl
parent efe93e31b1
commit dc09d5d34d
2 changed files with 61 additions and 8 deletions

View File

@@ -28,6 +28,7 @@ import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.convert.Jsr310Converters;
import org.springframework.data.util.NullableWrapperConverters;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -43,6 +44,7 @@ import org.springframework.util.ConcurrentReferenceHashMap;
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
* @author Jens Schauder
* @see SpelAwareProxyProjectionFactory
* @since 1.10
*/
@@ -51,6 +53,7 @@ class ProxyProjectionFactory implements ProjectionFactory, BeanClassLoaderAware
final static GenericConversionService CONVERSION_SERVICE = new DefaultConversionService();
static {
Jsr310Converters.getConvertersToRegister().forEach(CONVERSION_SERVICE::addConverter);
NullableWrapperConverters.registerConvertersIn(CONVERSION_SERVICE);
CONVERSION_SERVICE.removeConvertible(Object.class, Object.class);
}

View File

@@ -19,7 +19,11 @@ import static org.assertj.core.api.Assertions.*;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Proxy;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -37,6 +41,8 @@ import org.springframework.test.util.ReflectionTestUtils;
* @author Oliver Gierke
* @author Wim Deblauwe
* @author Mark Paluch
* @author Jens Schauder
* @author Christoph Strobl
*/
class ProxyProjectionFactoryUnitTests {
@@ -276,17 +282,47 @@ class ProxyProjectionFactoryUnitTests {
});
}
@Test // DATACMNS-1836
void supportsDateToLocalDateTimeConversion() {
Customer customer = new Customer();
customer.firstname = "Dave";
customer.birthdate = new GregorianCalendar(1967, Calendar.JANUARY, 9).getTime();
customer.address = new Address();
customer.address.city = "New York";
customer.address.zipCode = "ZIP";
CustomerWithLocalDateTime excerpt = factory.createProjection(CustomerWithLocalDateTime.class, customer);
assertThat(excerpt.getFirstname()).isEqualTo("Dave");
assertThat(excerpt.getBirthdate()).isEqualTo(LocalDateTime.of(1967, 1, 9, 0, 0));
}
@Test // DATACMNS-1836
void supportsNullableWrapperDateToLocalDateTimeConversion() {
Customer customer = new Customer();
customer.firstname = "Dave";
customer.birthdate = new GregorianCalendar(1967, Calendar.JANUARY, 9).getTime();
customer.address = new Address();
customer.address.city = "New York";
customer.address.zipCode = "ZIP";
CustomerWithOptional excerpt = factory.createProjection(CustomerWithOptional.class, customer);
assertThat(excerpt.getFirstname()).isEqualTo("Dave");
assertThat(excerpt.getBirthdate()).contains(LocalDateTime.of(1967, 1, 9, 0, 0));
}
interface Contact {}
static class Customer implements Contact {
interface CustomerWithLocalDateTime {
Long id;
String firstname, lastname;
Address address;
byte[] picture;
Address[] shippingAddresses;
Map<String, Object> data;
Optional<String> optional;
String getFirstname();
LocalDateTime getBirthdate();
}
static class Address {
@@ -328,6 +364,8 @@ class ProxyProjectionFactoryUnitTests {
Optional<byte[]> getPicture();
Optional<String> getOptional();
Optional<LocalDateTime> getBirthdate();
}
interface CustomerWithOptionalHavingProjection {
@@ -336,4 +374,16 @@ class ProxyProjectionFactoryUnitTests {
Optional<AddressExcerpt> getAddress();
}
static class Customer implements Contact {
Long id;
String firstname, lastname;
Date birthdate;
Address address;
byte[] picture;
Address[] shippingAddresses;
Map<String, Object> data;
Optional<String> optional;
}
}