DATACASS-349 - Consider custom write converters for collection types.

We now consider registered custom write converters for top-level collection types (like Map<String, Collection<String>>) to convert properties to Java types. Previously, only collection component types and non-collection top-level types were used to determine a converter.
This commit is contained in:
Mark Paluch
2016-10-24 15:03:32 +02:00
parent 6b683f4346
commit fcd383ef15
2 changed files with 77 additions and 6 deletions

View File

@@ -269,6 +269,10 @@ public class BasicCassandraMappingContext
return property.getDataType();
}
if (customConversions.hasCustomWriteTarget(property.getType())) {
return getDataTypeFor(customConversions.getCustomWriteTarget(property.getType()));
}
if (customConversions.hasCustomWriteTarget(property.getActualType())) {
Class<?> targetType = customConversions.getCustomWriteTarget(property.getActualType());
@@ -285,7 +289,6 @@ public class BasicCassandraMappingContext
}
return getDataTypeFor(targetType);
}
return property.getDataType();

View File

@@ -19,22 +19,27 @@ import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.springframework.cassandra.core.Ordering;
import org.springframework.cassandra.core.PrimaryKeyType;
import org.springframework.cassandra.core.cql.CqlIdentifier;
import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator;
import org.springframework.cassandra.core.keyspace.ColumnSpecification;
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.annotation.Id;
import org.springframework.data.cassandra.convert.CustomConversions;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.util.ClassTypeInformation;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.DataType.Name;
/**
* Unit tests for {@link BasicCassandraMappingContext}.
*
@@ -322,19 +327,82 @@ public class BasicCassandraMappingContextUnitTests {
@Test
public void shouldNotCreateEntitiesForCustomConvertedTypes() {
List<?> converters = Arrays.asList(new HumanToStringConverter());
mappingContext.setCustomConversions(new CustomConversions(converters));
mappingContext
.setCustomConversions(new CustomConversions(Collections.singletonList(HumanToStringConverter.INSTANCE)));
assertThat(mappingContext.shouldCreatePersistentEntityFor(ClassTypeInformation.from(Human.class)), is(false));
}
/**
* @see DATACASS-349
*/
@Test
public void propertyTypeShouldConsiderRegisteredConverterForPropertyType() {
mappingContext
.setCustomConversions(new CustomConversions(Collections.singletonList(StringMapToStringConverter.INSTANCE)));
CassandraPersistentEntity<?> persistentEntity = mappingContext
.getPersistentEntity(TypeWithCustomConvertedMap.class);
assertThat(mappingContext.getDataType(persistentEntity.getPersistentProperty("stringMap")),
is(equalTo(DataType.varchar())));
assertThat(mappingContext.getDataType(persistentEntity.getPersistentProperty("blobMap")),
is(equalTo(DataType.ascii())));
}
/**
* @see DATACASS-349
*/
@Test
public void propertyTypeShouldConsiderRegisteredConverterForCollectionComponentType() {
mappingContext
.setCustomConversions(new CustomConversions(Collections.singletonList(HumanToStringConverter.INSTANCE)));
CassandraPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(TypeWithListOfHumans.class);
assertThat(mappingContext.getDataType(persistentEntity.getPersistentProperty("humans")),
is(equalTo((DataType) DataType.list(DataType.varchar()))));
}
private static class Human {}
private static class HumanToStringConverter implements Converter<Human, String> {
enum HumanToStringConverter implements Converter<Human, String> {
INSTANCE;
@Override
public String convert(Human source) {
return "hello";
}
}
@Table
private static class TypeWithCustomConvertedMap {
@Id String id;
Map<String, Collection<String>> stringMap;
@CassandraType(type = Name.ASCII) Map<String, Collection<String>> blobMap;
}
@Table
private static class TypeWithListOfHumans {
@Id String id;
List<Human> humans;
}
@WritingConverter
enum StringMapToStringConverter implements Converter<Map<String, Collection<String>>, String> {
INSTANCE;
@Override
public String convert(Map<String, Collection<String>> source) {
return "serialized";
}
}
}