|
16 | 16 | package org.springframework.data.mapping.model;
|
17 | 17 |
|
18 | 18 | import static org.assertj.core.api.Assertions.*;
|
| 19 | +import static org.mockito.ArgumentMatchers.*; |
19 | 20 | import static org.mockito.Mockito.*;
|
20 | 21 |
|
21 | 22 | import lombok.AllArgsConstructor;
|
22 | 23 | import lombok.Data;
|
23 | 24 | import lombok.Value;
|
24 | 25 |
|
| 26 | +import java.util.stream.Stream; |
| 27 | + |
| 28 | +import org.junit.jupiter.api.DynamicTest; |
| 29 | +import org.junit.jupiter.api.Named; |
25 | 30 | import org.junit.jupiter.api.Test;
|
| 31 | +import org.junit.jupiter.api.TestFactory; |
26 | 32 | import org.springframework.core.convert.ConversionService;
|
27 | 33 | import org.springframework.core.convert.support.DefaultConversionService;
|
| 34 | +import org.springframework.data.mapping.PersistentEntity; |
| 35 | +import org.springframework.data.mapping.PersistentProperty; |
28 | 36 | import org.springframework.data.mapping.PersistentPropertyAccessor;
|
29 | 37 | import org.springframework.data.mapping.PersistentPropertyPath;
|
30 | 38 | import org.springframework.data.mapping.context.SampleMappingContext;
|
@@ -133,6 +141,40 @@ public void shouldConvertToPropertyPathLeafType() {
|
133 | 141 | assertThat(convertingAccessor.getBean().getCustomer().getFirstname()).isEqualTo("2");
|
134 | 142 | }
|
135 | 143 |
|
| 144 | + @TestFactory // #2546 |
| 145 | + Stream<DynamicTest> doesNotInvokeConversionForMatchingPrimitives() { |
| 146 | + |
| 147 | + IntegerWrapper wrapper = new IntegerWrapper(); |
| 148 | + wrapper.primitive = 42; |
| 149 | + wrapper.boxed = 42; |
| 150 | + |
| 151 | + SampleMappingContext context = new SampleMappingContext(); |
| 152 | + PersistentEntity<Object, SamplePersistentProperty> entity = context |
| 153 | + .getRequiredPersistentEntity(IntegerWrapper.class); |
| 154 | + |
| 155 | + SamplePersistentProperty primitiveProperty = entity.getRequiredPersistentProperty("primitive"); |
| 156 | + SamplePersistentProperty boxedProperty = entity.getRequiredPersistentProperty("boxed"); |
| 157 | + |
| 158 | + PersistentPropertyAccessor<IntegerWrapper> accessor = entity.getPropertyAccessor(wrapper); |
| 159 | + ConversionService conversionService = mock(ConversionService.class); |
| 160 | + |
| 161 | + ConvertingPropertyAccessor<IntegerWrapper> convertingAccessor = new ConvertingPropertyAccessor<>(accessor, |
| 162 | + conversionService); |
| 163 | + |
| 164 | + Stream<PrimitiveFixture> fixtures = Stream.of( |
| 165 | + PrimitiveFixture.$(boxedProperty, int.class), |
| 166 | + PrimitiveFixture.$(boxedProperty, Integer.class), |
| 167 | + PrimitiveFixture.$(primitiveProperty, int.class), |
| 168 | + PrimitiveFixture.$(primitiveProperty, Integer.class)); |
| 169 | + |
| 170 | + return DynamicTest.stream(fixtures, it -> { |
| 171 | + |
| 172 | + convertingAccessor.getProperty(it.property, it.type); |
| 173 | + |
| 174 | + verify(conversionService, never()).convert(any(), eq(it.type)); |
| 175 | + }); |
| 176 | + } |
| 177 | + |
136 | 178 | private static ConvertingPropertyAccessor getAccessor(Object entity, ConversionService conversionService) {
|
137 | 179 |
|
138 | 180 | PersistentPropertyAccessor wrapper = new BeanWrapper<>(entity);
|
@@ -161,4 +203,26 @@ static class Order {
|
161 | 203 | static class Customer {
|
162 | 204 | String firstname;
|
163 | 205 | }
|
| 206 | + |
| 207 | + static class IntegerWrapper { |
| 208 | + int primitive; |
| 209 | + Integer boxed; |
| 210 | + } |
| 211 | + |
| 212 | + @Value(staticConstructor = "$") |
| 213 | + static class PrimitiveFixture implements Named<PrimitiveFixture> { |
| 214 | + |
| 215 | + PersistentProperty<?> property; |
| 216 | + Class<?> type; |
| 217 | + |
| 218 | + @Override |
| 219 | + public String getName() { |
| 220 | + return String.format("Accessing %s as %s does not cause conversion.", property, type); |
| 221 | + } |
| 222 | + |
| 223 | + @Override |
| 224 | + public PrimitiveFixture getPayload() { |
| 225 | + return this; |
| 226 | + } |
| 227 | + } |
164 | 228 | }
|
0 commit comments