|
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