Skip to content

Commit 6a4dddd

Browse files
committed
Correctly write Where for entities using composite primary key classes with user-defined types.
We now correctly write properties from composite primary keys to the Where condition object. Previously, the object write used writeWhereFromObject(…) that isn't converter/UDT/tuple-type-aware. Closes #1137.
1 parent 789be0d commit 6a4dddd

File tree

2 files changed

+96
-25
lines changed

2 files changed

+96
-25
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverter.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ public void write(Object source, Object sink, CassandraPersistentEntity<?> entit
482482
if (sink instanceof Where) {
483483
writeWhereFromObject(source, (Where) sink, entity);
484484
} else if (sink instanceof Map) {
485-
writeMapFromWrapper(newConvertingPropertyAccessor(source, entity), (Map<CqlIdentifier, Object>) sink, entity);
485+
writeInternal(newConvertingPropertyAccessor(source, entity), (Map<CqlIdentifier, Object>) sink, entity);
486486
} else if (sink instanceof TupleValue) {
487487
writeTupleValue(newConvertingPropertyAccessor(source, entity), (TupleValue) sink, entity);
488488
} else if (sink instanceof UdtValue) {
@@ -492,7 +492,7 @@ public void write(Object source, Object sink, CassandraPersistentEntity<?> entit
492492
}
493493
}
494494

495-
private void writeMapFromWrapper(ConvertingPropertyAccessor<?> accessor, Map<CqlIdentifier, Object> sink,
495+
private void writeInternal(ConvertingPropertyAccessor<?> accessor, Map<CqlIdentifier, Object> sink,
496496
CassandraPersistentEntity<?> entity) {
497497

498498
for (CassandraPersistentProperty property : entity) {
@@ -511,7 +511,7 @@ private void writeMapFromWrapper(ConvertingPropertyAccessor<?> accessor, Map<Cql
511511

512512
CassandraPersistentEntity<?> compositePrimaryKey = getMappingContext().getRequiredPersistentEntity(property);
513513

514-
writeMapFromWrapper(newConvertingPropertyAccessor(value, compositePrimaryKey), sink, compositePrimaryKey);
514+
writeInternal(newConvertingPropertyAccessor(value, compositePrimaryKey), sink, compositePrimaryKey);
515515

516516
continue;
517517
}
@@ -583,8 +583,7 @@ private void writeWhereFromObject(Object source, Where sink, CassandraPersistent
583583

584584
CassandraPersistentEntity<?> compositePrimaryKey = getMappingContext()
585585
.getRequiredPersistentEntity(compositeIdProperty);
586-
587-
writeWhere(newConvertingPropertyAccessor(id, compositePrimaryKey), sink, compositePrimaryKey);
586+
writeInternal(newConvertingPropertyAccessor(id, compositePrimaryKey), sink, compositePrimaryKey);
588587
return;
589588
}
590589

spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverterUDTUnitTests.java

Lines changed: 92 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,10 @@
4242
import org.springframework.data.annotation.Id;
4343
import org.springframework.data.annotation.ReadOnlyProperty;
4444
import org.springframework.data.cassandra.core.StatementFactory;
45+
import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
4546
import org.springframework.data.cassandra.core.cql.WriteOptions;
4647
import org.springframework.data.cassandra.core.cql.util.StatementBuilder;
47-
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
48-
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
49-
import org.springframework.data.cassandra.core.mapping.CassandraType;
50-
import org.springframework.data.cassandra.core.mapping.Embedded;
51-
import org.springframework.data.cassandra.core.mapping.Frozen;
52-
import org.springframework.data.cassandra.core.mapping.Table;
53-
import org.springframework.data.cassandra.core.mapping.UserDefinedType;
54-
import org.springframework.data.cassandra.core.mapping.UserTypeResolver;
48+
import org.springframework.data.cassandra.core.mapping.*;
5549
import org.springframework.data.cassandra.support.UserDefinedTypeBuilder;
5650
import org.springframework.data.cassandra.test.util.RowMockUtil;
5751

@@ -127,10 +121,7 @@ void setUp() {
127121
@Test // DATACASS-172
128122
void shouldWriteMappedUdt() {
129123

130-
AddressUserType addressUserType = new AddressUserType();
131-
addressUserType.setZip("69469");
132-
addressUserType.setCity("Weinheim");
133-
addressUserType.setStreetLines(Arrays.asList("Heckenpfad", "14"));
124+
AddressUserType addressUserType = prepareAddressUserType();
134125

135126
AddressBook addressBook = new AddressBook();
136127
addressBook.setId("1");
@@ -146,10 +137,7 @@ void shouldWriteMappedUdt() {
146137
@Test // DATACASS-172
147138
void shouldWriteMappedUdtCollection() {
148139

149-
AddressUserType addressUserType = new AddressUserType();
150-
addressUserType.setZip("69469");
151-
addressUserType.setCity("Weinheim");
152-
addressUserType.setStreetLines(Arrays.asList("Heckenpfad", "14"));
140+
AddressUserType addressUserType = prepareAddressUserType();
153141

154142
AddressBook addressBook = new AddressBook();
155143
addressBook.setId("1");
@@ -188,10 +176,7 @@ void shouldWriteUdt() {
188176
@Test // DATACASS-172
189177
void shouldWriteUdtPk() {
190178

191-
AddressUserType addressUserType = new AddressUserType();
192-
addressUserType.setZip("69469");
193-
addressUserType.setCity("Weinheim");
194-
addressUserType.setStreetLines(Arrays.asList("Heckenpfad", "14"));
179+
AddressUserType addressUserType = prepareAddressUserType();
195180

196181
WithMappedUdtId withUdtId = new WithMappedUdtId();
197182
withUdtId.setId(addressUserType);
@@ -203,6 +188,72 @@ void shouldWriteUdtPk() {
203188
"INSERT INTO withmappedudtid (id) " + "VALUES ({zip:'69469',city:'Weinheim',streetlines:['Heckenpfad','14']})");
204189
}
205190

191+
@Test // #1137
192+
void shouldWriteCompositeUdtPk() {
193+
194+
AddressUserType addressUserType = prepareAddressUserType();
195+
196+
WithCompositePrimaryKey withUdt = new WithCompositePrimaryKey();
197+
withUdt.addressUserType = addressUserType;
198+
withUdt.id = "foo";
199+
200+
SimpleStatement statement = new StatementFactory(converter).insert(withUdt, WriteOptions.empty())
201+
.build(StatementBuilder.ParameterHandling.INLINE);
202+
203+
assertThat(statement.getQuery()).isEqualTo("INSERT INTO withcompositeprimarykey (id,addressusertype) "
204+
+ "VALUES ('foo',{zip:'69469',city:'Weinheim',streetlines:['Heckenpfad','14']})");
205+
}
206+
207+
private static AddressUserType prepareAddressUserType() {
208+
209+
AddressUserType addressUserType = new AddressUserType();
210+
addressUserType.setZip("69469");
211+
addressUserType.setCity("Weinheim");
212+
addressUserType.setStreetLines(Arrays.asList("Heckenpfad", "14"));
213+
214+
return addressUserType;
215+
}
216+
217+
@Test // #1137
218+
void shouldWriteCompositeUdtPkClass() {
219+
220+
WithCompositePrimaryKeyClassWithUdt object = prepareCompositePrimaryKeyClassWithUdt();
221+
222+
SimpleStatement statement = new StatementFactory(converter).insert(object, WriteOptions.empty())
223+
.build(StatementBuilder.ParameterHandling.INLINE);
224+
225+
assertThat(statement.getQuery())
226+
.isEqualTo("INSERT INTO withcompositeprimarykeyclasswithudt (id,addressusertype,currency) "
227+
+ "VALUES ('foo',{zip:'69469',city:'Weinheim',streetlines:['Heckenpfad','14']},{currency:'EUR'})");
228+
}
229+
230+
@Test // #1137
231+
void shouldWriteCompositeUdtPkClassToWhere() {
232+
233+
WithCompositePrimaryKeyClassWithUdt object = prepareCompositePrimaryKeyClassWithUdt();
234+
235+
Where where = new Where();
236+
converter.write(object, where);
237+
238+
assertThat((UdtValue) where.get(CqlIdentifier.fromCql("currency"))) //
239+
.extracting(UdtValue::getFormattedContents) //
240+
.isEqualTo("{currency:'EUR'}");
241+
}
242+
243+
private static WithCompositePrimaryKeyClassWithUdt prepareCompositePrimaryKeyClassWithUdt() {
244+
245+
AddressUserType addressUserType = prepareAddressUserType();
246+
247+
CompositePrimaryKeyClassWithUdt withUdt = new CompositePrimaryKeyClassWithUdt();
248+
withUdt.addressUserType = addressUserType;
249+
withUdt.id = "foo";
250+
withUdt.currency = new Currency("EUR");
251+
252+
WithCompositePrimaryKeyClassWithUdt object = new WithCompositePrimaryKeyClassWithUdt();
253+
object.id = withUdt;
254+
return object;
255+
}
256+
206257
@Test // DATACASS-172
207258
void shouldWriteMappedUdtPk() {
208259

@@ -585,6 +636,27 @@ public static class Money {
585636
@Id private Currency currency;
586637
}
587638

639+
@Data
640+
@Table
641+
public static class WithCompositePrimaryKey {
642+
@PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED) String id;
643+
@PrimaryKeyColumn(ordinal = 1) AddressUserType addressUserType;
644+
}
645+
646+
@Data
647+
@Table
648+
public static class WithCompositePrimaryKeyClassWithUdt {
649+
@PrimaryKey CompositePrimaryKeyClassWithUdt id;
650+
}
651+
652+
@Data
653+
@PrimaryKeyClass
654+
public static class CompositePrimaryKeyClassWithUdt {
655+
@PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED) String id;
656+
@PrimaryKeyColumn(ordinal = 1) AddressUserType addressUserType;
657+
@PrimaryKeyColumn(ordinal = 2) Currency currency;
658+
}
659+
588660
@Table
589661
@AllArgsConstructor
590662
@Getter

0 commit comments

Comments
 (0)