|
24 | 24 | import java.math.BigInteger; |
25 | 25 | import java.net.InetAddress; |
26 | 26 | import java.net.UnknownHostException; |
| 27 | +import java.nio.ByteBuffer; |
27 | 28 | import java.time.Instant; |
28 | 29 | import java.time.LocalDate; |
29 | 30 | import java.time.LocalDateTime; |
30 | 31 | import java.time.ZoneId; |
31 | 32 | import java.time.ZoneOffset; |
32 | 33 | import java.util.*; |
33 | 34 |
|
| 35 | +import org.assertj.core.data.Percentage; |
34 | 36 | import org.json.simple.JSONObject; |
35 | 37 | import org.json.simple.parser.JSONParser; |
36 | 38 | import org.json.simple.parser.ParseException; |
|
55 | 57 | import org.springframework.data.cassandra.domain.UserToken; |
56 | 58 | import org.springframework.data.cassandra.support.UserDefinedTypeBuilder; |
57 | 59 | import org.springframework.data.cassandra.test.util.RowMockUtil; |
| 60 | +import org.springframework.data.convert.ReadingConverter; |
58 | 61 | import org.springframework.data.convert.SimplePropertyValueConversions; |
59 | 62 | import org.springframework.data.convert.ValueConverter; |
60 | 63 | import org.springframework.data.projection.EntityProjection; |
@@ -88,9 +91,13 @@ public class MappingCassandraConverterUnitTests { |
88 | 91 | @BeforeEach |
89 | 92 | void setUp() { |
90 | 93 |
|
| 94 | + CassandraCustomConversions conversions = new CassandraCustomConversions( |
| 95 | + List.of(new ByteBufferToDoubleHolderConverter())); |
91 | 96 | this.mappingContext = new CassandraMappingContext(); |
| 97 | + this.mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder()); |
92 | 98 |
|
93 | 99 | this.converter = new MappingCassandraConverter(mappingContext); |
| 100 | + this.converter.setCustomConversions(conversions); |
94 | 101 | this.converter.afterPropertiesSet(); |
95 | 102 | } |
96 | 103 |
|
@@ -1074,6 +1081,27 @@ void shouldCreateDtoProjectionsThroughConstructor() { |
1074 | 1081 | assertThat(result.tuple().one).isEqualTo("One"); |
1075 | 1082 | } |
1076 | 1083 |
|
| 1084 | + @Test // GH-1472 |
| 1085 | + void projectShouldReadDtoProjectionPropertiesOnlyOnce() { |
| 1086 | + |
| 1087 | + ByteBuffer number = ByteBuffer.allocate(8); |
| 1088 | + number.putDouble(1.2d); |
| 1089 | + number.flip(); |
| 1090 | + |
| 1091 | + rowMock = RowMockUtil.newRowMock(RowMockUtil.column("number", number, DataTypes.BLOB)); |
| 1092 | + |
| 1093 | + EntityProjectionIntrospector introspector = EntityProjectionIntrospector.create( |
| 1094 | + new SpelAwareProxyProjectionFactory(), EntityProjectionIntrospector.ProjectionPredicate.typeHierarchy(), |
| 1095 | + this.mappingContext); |
| 1096 | + |
| 1097 | + EntityProjection<DoubleHolderDto, WithDoubleHolder> projection = introspector.introspect(DoubleHolderDto.class, |
| 1098 | + WithDoubleHolder.class); |
| 1099 | + |
| 1100 | + DoubleHolderDto result = this.converter.project(projection, rowMock); |
| 1101 | + |
| 1102 | + assertThat(result.number.number).isCloseTo(1.2, Percentage.withPercentage(1)); |
| 1103 | + } |
| 1104 | + |
1077 | 1105 | @Test // GH-1471 |
1078 | 1106 | void propertyValueConversionsCacheShouldConsiderPropertyEquality() { |
1079 | 1107 |
|
@@ -1770,4 +1798,29 @@ public void setLastName(String lastName) { |
1770 | 1798 | this.lastName = lastName; |
1771 | 1799 | } |
1772 | 1800 | } |
| 1801 | + |
| 1802 | + @ReadingConverter |
| 1803 | + static class ByteBufferToDoubleHolderConverter implements Converter<ByteBuffer, DoubleHolder> { |
| 1804 | + |
| 1805 | + @Override |
| 1806 | + public DoubleHolder convert(ByteBuffer source) { |
| 1807 | + return new DoubleHolder(source.getDouble()); |
| 1808 | + } |
| 1809 | + } |
| 1810 | + |
| 1811 | + record DoubleHolder(double number) { |
| 1812 | + |
| 1813 | + } |
| 1814 | + |
| 1815 | + static class WithDoubleHolder { |
| 1816 | + DoubleHolder number; |
| 1817 | + } |
| 1818 | + |
| 1819 | + static class DoubleHolderDto { |
| 1820 | + DoubleHolder number; |
| 1821 | + |
| 1822 | + public DoubleHolderDto(DoubleHolder number) { |
| 1823 | + this.number = number; |
| 1824 | + } |
| 1825 | + } |
1773 | 1826 | } |
0 commit comments