From fcd383ef155a8a55ce80809a414172af3ca51393 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 24 Oct 2016 15:03:32 +0200 Subject: [PATCH] DATACASS-349 - Consider custom write converters for collection types. We now consider registered custom write converters for top-level collection types (like Map>) to convert properties to Java types. Previously, only collection component types and non-collection top-level types were used to determine a converter. --- .../mapping/BasicCassandraMappingContext.java | 5 +- ...BasicCassandraMappingContextUnitTests.java | 78 +++++++++++++++++-- 2 files changed, 77 insertions(+), 6 deletions(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java index 78b3383b9..713ab5113 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java @@ -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(); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java index dcfbc1087..f96319fae 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java @@ -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 { + enum HumanToStringConverter implements Converter { + + INSTANCE; @Override public String convert(Human source) { return "hello"; } } + + @Table + private static class TypeWithCustomConvertedMap { + + @Id String id; + Map> stringMap; + + @CassandraType(type = Name.ASCII) Map> blobMap; + } + + @Table + private static class TypeWithListOfHumans { + + @Id String id; + List humans; + } + + @WritingConverter + enum StringMapToStringConverter implements Converter>, String> { + + INSTANCE; + + @Override + public String convert(Map> source) { + return "serialized"; + } + } }