Fix DTO projection instantiation.
We now correctly instantiate DTO projection classes by using the actual constructor argument type. Previously, we did not update the conversion context to fetch the correct type but used the type of the DTO projection class instead of the constructor argument. Closes #1292
This commit is contained in:
@@ -1427,11 +1427,11 @@ public class MappingCassandraConverter extends AbstractCassandraConverter
|
||||
name, entity.getType()));
|
||||
}
|
||||
|
||||
return (T) getReadValue(context, provider, property);
|
||||
return (T) getReadValue(context.forProperty(property.getName()), provider, property);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <T> CassandraPersistentProperty getPersistentProperty(String name, TypeInformation<?> typeInformation,
|
||||
private CassandraPersistentProperty getPersistentProperty(String name, TypeInformation<?> typeInformation,
|
||||
MergedAnnotations annotations) {
|
||||
|
||||
CassandraPersistentProperty property = entity.getPersistentProperty(name);
|
||||
|
||||
@@ -964,6 +964,33 @@ public class MappingCassandraConverterUnitTests {
|
||||
assertThat(result.getTuple().getOne()).isEqualTo("One");
|
||||
}
|
||||
|
||||
@Test // GH-1202
|
||||
void shouldCreateDtoProjectionsThroughConstructor() {
|
||||
|
||||
DefaultTupleValue value = new DefaultTupleValue(
|
||||
new DefaultTupleType(Arrays.asList(DataTypes.ASCII, DataTypes.ASCII, DataTypes.ASCII)));
|
||||
|
||||
value.setString(0, "Zero");
|
||||
value.setString(1, "One");
|
||||
value.setString(2, "Two");
|
||||
|
||||
EntityProjectionIntrospector introspector = EntityProjectionIntrospector.create(
|
||||
new SpelAwareProxyProjectionFactory(), EntityProjectionIntrospector.ProjectionPredicate.typeHierarchy(),
|
||||
this.mappingContext);
|
||||
|
||||
rowMock = RowMockUtil.newRowMock(RowMockUtil.column("firstname", "Heisenberg", DataTypes.ASCII),
|
||||
RowMockUtil.column("tuple", value, value.getType()));
|
||||
|
||||
EntityProjection<TupleAndNameProjection, WithMappedTuple> projection = introspector
|
||||
.introspect(TupleAndNameProjection.class, WithMappedTuple.class);
|
||||
|
||||
TupleAndNameProjection result = this.mappingCassandraConverter.project(projection, rowMock);
|
||||
|
||||
assertThat(result.getName().getFirstname()).isEqualTo("Heisenberg");
|
||||
assertThat(result.getTuple().zero).isEqualTo("Zero");
|
||||
assertThat(result.getTuple().one).isEqualTo("One");
|
||||
}
|
||||
|
||||
private static List<Object> getValues(Map<CqlIdentifier, Object> statement) {
|
||||
return new ArrayList<>(statement.values());
|
||||
}
|
||||
@@ -1204,9 +1231,15 @@ public class MappingCassandraConverterUnitTests {
|
||||
private static class WithMappedTuple {
|
||||
|
||||
String firstname;
|
||||
@Embedded.Nullable Name name;
|
||||
TupleWithElementAnnotationInConstructor tuple;
|
||||
}
|
||||
|
||||
@lombok.Value
|
||||
private static class Name {
|
||||
String firstname;
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class WithMappedTupleDtoProjection {
|
||||
|
||||
@@ -1214,6 +1247,14 @@ public class MappingCassandraConverterUnitTests {
|
||||
TupleProjection tuple;
|
||||
}
|
||||
|
||||
@lombok.Value
|
||||
private static class TupleAndNameProjection {
|
||||
|
||||
@Embedded.Nullable Name name;
|
||||
|
||||
TupleWithElementAnnotationInConstructor tuple;
|
||||
}
|
||||
|
||||
private static interface TupleProjection {
|
||||
|
||||
String getZero();
|
||||
|
||||
Reference in New Issue
Block a user