DATACASS-607 - Consider custom conversion for collections based on read converter.

We now apply custom conversions for collection elements if a read converter is registered. Previously, we used the presence/absence of a write converter to initiate conversion for collections.
This commit is contained in:
Mark Paluch
2018-11-13 15:06:53 +01:00
parent ada4bc0ab1
commit 95fc0a55b4
2 changed files with 54 additions and 51 deletions

View File

@@ -961,23 +961,6 @@ public class MappingCassandraConverter extends AbstractCassandraConverter
@SuppressWarnings("unchecked")
private Object convertReadValue(Object value, TypeInformation<?> typeInformation) {
if (getCustomConversions().hasCustomWriteTarget(typeInformation.getRequiredActualType().getType())
&& typeInformation.isCollectionLike()) {
if (value instanceof Collection) {
Collection<Object> original = (Collection<Object>) value;
Collection<Object> converted = CollectionFactory.createCollection(typeInformation.getType(), original.size());
for (Object element : original) {
converted.add(getConversionService().convert(element, typeInformation.getRequiredActualType().getType()));
}
return converted;
}
}
if (typeInformation.isCollectionLike() && value instanceof Collection) {
return readCollectionOrArrayInternal((Collection<?>) value, typeInformation);
}
@@ -1034,16 +1017,14 @@ public class MappingCassandraConverter extends AbstractCassandraConverter
BasicCassandraPersistentEntity<?> entity = getMappingContext().getPersistentEntity(elementType);
if (entity != null) {
if (entity != null && entity.isUserDefinedType()) {
for (Object element : source) {
collection.add(readEntityFromUdt(entity, (UDTValue) element));
}
if (entity.isUserDefinedType()) {
for (Object udtValue : source) {
collection.add(readEntityFromUdt(entity, (UDTValue) udtValue));
}
} else if (entity.isTupleType()) {
for (Object tupleValue : source) {
collection.add(readEntityFromTuple(entity, (TupleValue) tupleValue));
}
} else if (entity != null && entity.isTupleType()) {
for (Object element : source) {
collection.add(readEntityFromTuple(entity, (TupleValue) element));
}
} else {
for (Object element : source) {

View File

@@ -27,6 +27,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import org.junit.Before;
import org.junit.Test;
@@ -57,19 +58,7 @@ public class CustomConversionIntegrationTests extends AbstractKeyspaceCreatingIn
@Before
public void setUp() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(new PersonReadConverter());
converters.add(new PersonWriteConverter());
CustomConversions customConversions = new CassandraCustomConversions(converters);
CassandraMappingContext mappingContext = new CassandraMappingContext();
mappingContext.setCustomConversions(customConversions);
mappingContext.afterPropertiesSet();
MappingCassandraConverter converter = new MappingCassandraConverter(mappingContext);
converter.setCustomConversions(customConversions);
converter.afterPropertiesSet();
MappingCassandraConverter converter = createConverter();
cassandraOperations = new CassandraTemplate(session, converter);
SchemaTestUtils.potentiallyCreateTableFor(Employee.class, cassandraOperations);
@@ -179,19 +168,55 @@ public class CustomConversionIntegrationTests extends AbstractKeyspaceCreatingIn
assertThat(employee.getPeople()).extracting(Person::getFirstname).contains("Apu");
}
@Test // DATACASS-296
public void dummy() {
@Test // DATACASS-607
public void shouldApplyCustomReadConverterIfOnlyReadIsCustomized() {
cassandraOperations.getCqlOperations().execute(QueryBuilder.insertInto("employee").value("id", "employee-id"));
MappingCassandraConverter converter = createConverter(converters -> {
converters.add(new PersonReadConverter());
});
cassandraOperations = new CassandraTemplate(session, converter);
cassandraOperations.getCqlOperations().execute(QueryBuilder.insertInto("employee").value("id", "employee-id")
.value("people", Collections.singleton("{\"firstname\":\"Apu\",\"lastname\":\"Nahasapeemapetilon\"}")));
Employee employee = cassandraOperations.selectOne(QueryBuilder.select("id", "people").from("employee"),
Employee.class);
assertThat(employee.getId()).isEqualTo("employee-id");
assertThat(employee.getPeople()).isNotNull().hasSize(1);
assertThat(employee.getPeople()).extracting(Person::getFirstname).contains("Apu");
cassandraOperations.getCqlOperations()
.execute(QueryBuilder.update("employee").where(QueryBuilder.eq("id", "employee-id")).with(QueryBuilder
.set("people", Collections.singleton("{\"firstname\":\"Apu\",\"lastname\":\"Nahasapeemapetilon\"}"))));
}
/**
* @author Mark Paluch
*/
private static MappingCassandraConverter createConverter() {
return createConverter(converters -> {
converters.add(new PersonReadConverter());
converters.add(new PersonWriteConverter());
});
}
private static MappingCassandraConverter createConverter(Consumer<List<Converter<?, ?>>> converterCustomizer) {
List<Converter<?, ?>> converters = new ArrayList<>();
converterCustomizer.accept(converters);
CustomConversions customConversions = new CassandraCustomConversions(converters);
CassandraMappingContext mappingContext = new CassandraMappingContext();
mappingContext.setCustomConversions(customConversions);
mappingContext.afterPropertiesSet();
MappingCassandraConverter converter = new MappingCassandraConverter(mappingContext);
converter.setCustomConversions(customConversions);
converter.afterPropertiesSet();
return converter;
}
@Data
@Table
static class Employee {
@@ -203,9 +228,6 @@ public class CustomConversionIntegrationTests extends AbstractKeyspaceCreatingIn
Set<Person> people;
}
/**
* @author Mark Paluch
*/
@Data
@AllArgsConstructor
@NoArgsConstructor