diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java index 7913c802d..ff70d7d7c 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java @@ -737,15 +737,22 @@ public class MappingCassandraConverter extends AbstractCassandraConverter return null; } - if (getCustomConversions().isSimpleType(value.getClass())) { - // Doesn't need conversion - return getPotentiallyConvertedSimpleValue(value, typeInformation.getType()); + Class requestedTargetType = typeInformation != null ? typeInformation.getType() : Object.class; + + if (getCustomConversions().hasCustomWriteTarget(value.getClass(), requestedTargetType)) { + return getConversionService().convert(value, + getCustomConversions().getCustomWriteTarget(value.getClass(), requestedTargetType)); } if (getCustomConversions().hasCustomWriteTarget(value.getClass())) { return getConversionService().convert(value, getCustomConversions().getCustomWriteTarget(value.getClass())); } + if (getCustomConversions().isSimpleType(value.getClass())) { + // Doesn't need conversion + return getPotentiallyConvertedSimpleValue(value, typeInformation.getType()); + } + TypeInformation type = (typeInformation != null ? typeInformation : ClassTypeInformation.from(value.getClass())); TypeInformation actualType = type.getActualType(); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/domain/Person.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/domain/Person.java index 60bcf51e0..2e401e7c1 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/domain/Person.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/domain/Person.java @@ -19,8 +19,11 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Id; import org.springframework.data.cassandra.mapping.Table; +import org.springframework.data.convert.ReadingConverter; +import org.springframework.data.convert.WritingConverter; /** * @author Mark Paluch @@ -34,4 +37,43 @@ public class Person { @Id String id; String firstname; String lastname; + + private Kindness kindness; + + public enum Kindness { + + Nice("+"), Rude("-"); + + private final String identifier; + + Kindness(String identifier) { + this.identifier = identifier; + } + + public String getIdentifier() { + return identifier; + } + } + + @WritingConverter + public enum KindnessToStringConverter implements Converter { + + INSTANCE; + + @Override + public String convert(Kindness source) { + return source.getIdentifier(); + } + } + + @ReadingConverter + public enum StringToKindnessConverter implements Converter { + + INSTANCE; + + @Override + public Kindness convert(String source) { + return "+".equals(source) ? Kindness.Nice : Kindness.Rude; + } + } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessorUnitTests.java index b9a4847e7..8e801a4b6 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessorUnitTests.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; import java.time.LocalDate; +import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -28,7 +29,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.cassandra.convert.CustomConversions; import org.springframework.data.cassandra.convert.MappingCassandraConverter; +import org.springframework.data.cassandra.domain.Person.Kindness; +import org.springframework.data.cassandra.domain.Person.KindnessToStringConverter; +import org.springframework.data.cassandra.domain.Person.StringToKindnessConverter; import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext; import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; import org.springframework.data.cassandra.mapping.CassandraType; @@ -43,7 +48,6 @@ import com.datastax.driver.core.DataType; * * @author Mark Paluch */ -@SuppressWarnings("Since15") @RunWith(MockitoJUnitRunner.class) public class ConvertingParameterAccessorUnitTests { @@ -56,7 +60,11 @@ public class ConvertingParameterAccessorUnitTests { @Before public void setUp() { + CustomConversions conversions = new CustomConversions( + Arrays.asList(KindnessToStringConverter.INSTANCE, StringToKindnessConverter.INSTANCE)); + this.converter = new MappingCassandraConverter(new BasicCassandraMappingContext()); + this.converter.setCustomConversions(conversions); this.converter.afterPropertiesSet(); this.convertingParameterAccessor = new ConvertingParameterAccessor(converter, mockParameterAccessor); } @@ -69,6 +77,16 @@ public class ConvertingParameterAccessorUnitTests { assertThat(accessor.getBindableValue(0)).isNull(); } + @Test // DATACASS-521 + public void shouldApplyCustomConverters() { + + when(mockParameterAccessor.getBindableValue(0)).thenReturn(Kindness.Nice); + + ConvertingParameterAccessor accessor = new ConvertingParameterAccessor(converter, mockParameterAccessor); + + assertThat(accessor.getBindableValue(0)).isEqualTo("+"); + } + @Test // DATACASS-296 @SuppressWarnings({ "rawtypes", "unchecked" }) public void shouldReturnNativeBindableValue() { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQueryUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQueryUnitTests.java index a29e28581..87b5dcdd1 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQueryUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQueryUnitTests.java @@ -34,8 +34,12 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.cassandra.core.cql.CqlIdentifier; +import org.springframework.data.cassandra.convert.CustomConversions; import org.springframework.data.cassandra.convert.MappingCassandraConverter; import org.springframework.data.cassandra.core.CassandraOperations; +import org.springframework.data.cassandra.domain.Person.Kindness; +import org.springframework.data.cassandra.domain.Person.KindnessToStringConverter; +import org.springframework.data.cassandra.domain.Person.StringToKindnessConverter; import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext; import org.springframework.data.cassandra.mapping.UserTypeResolver; import org.springframework.data.cassandra.repository.Query; @@ -90,8 +94,12 @@ public class StringBasedCassandraQueryUnitTests { @Before public void setUp() { + CustomConversions conversions = new CustomConversions( + Arrays.asList(KindnessToStringConverter.INSTANCE, StringToKindnessConverter.INSTANCE)); BasicCassandraMappingContext mappingContext = new BasicCassandraMappingContext(); + mappingContext.setCustomConversions(conversions); mappingContext.setUserTypeResolver(userTypeResolver); + mappingContext.afterPropertiesSet(); when(operations.getConverter()).thenReturn(converter); when(operations.getSession()).thenReturn(session); @@ -104,6 +112,7 @@ public class StringBasedCassandraQueryUnitTests { this.converter = new MappingCassandraConverter(mappingContext); this.factory = new SpelAwareProxyProjectionFactory(); + this.converter.setCustomConversions(conversions); this.converter.afterPropertiesSet(); } @@ -344,6 +353,19 @@ public class StringBasedCassandraQueryUnitTests { assertThat(stringQuery).isEqualTo("SELECT * FROM person WHERE address={city:NULL,country:NULL};"); } + @Test // DATACASS-521 + public void convertsEnumValueCorrectly() { + + StringBasedCassandraQuery cassandraQuery = getQueryMethod("findByCondition", Kindness.class); + + CassandraParameterAccessor accessor = new ConvertingParameterAccessor(converter, + new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), Kindness.Nice)); + + String query = cassandraQuery.createQuery(accessor); + + assertThat(query).isEqualTo("SELECT * FROM person WHERE kindness='+';"); + } + private StringBasedCassandraQuery getQueryMethod(String name, Class... args) { Method method = ReflectionUtils.findMethod(SampleRepository.class, name, args); CassandraQueryMethod queryMethod = new CassandraQueryMethod(method, metadata, factory, @@ -420,6 +442,9 @@ public class StringBasedCassandraQueryUnitTests { @Query("SELECT * FROM person WHERE address=?0;") Person findByMainAddress(UDTValue udtValue); + @Query("SELECT * FROM person WHERE kindness=?0;") + Person findByCondition(Kindness udtValue); + @ComposedQueryAnnotation Person findByComposedQueryAnnotation(String lastname); } @@ -428,4 +453,5 @@ public class StringBasedCassandraQueryUnitTests { @Query("SELECT * FROM person WHERE lastname = ?0;") @interface ComposedQueryAnnotation { } + } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepositoryIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepositoryIntegrationTests.java index 1e99771dd..38361da46 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepositoryIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepositoryIntegrationTests.java @@ -31,6 +31,7 @@ import org.springframework.cassandra.test.integration.AbstractKeyspaceCreatingIn import org.springframework.context.annotation.Configuration; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.domain.Person; +import org.springframework.data.cassandra.domain.Person.Kindness; import org.springframework.data.cassandra.repository.TypedIdCassandraRepository; import org.springframework.data.cassandra.test.integration.support.IntegrationTestConfig; import org.springframework.data.repository.query.DefaultEvaluationContextProvider; @@ -88,10 +89,10 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC repository.deleteAll(); - dave = new Person("42", "Dave", "Matthews"); - oliver = new Person("4", "Oliver August", "Matthews"); - carter = new Person("49", "Carter", "Beauford"); - boyd = new Person("45", "Boyd", "Tinsley"); + dave = new Person("42", "Dave", "Matthews", Kindness.Nice); + oliver = new Person("4", "Oliver August", "Matthews", Kindness.Nice); + carter = new Person("49", "Carter", "Beauford", Kindness.Nice); + boyd = new Person("45", "Boyd", "Tinsley", Kindness.Nice); repository.save(Arrays.asList(oliver, dave, carter, boyd)); } @@ -165,7 +166,7 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC repository.deleteAll(); - Person person = new Person("36", "Homer", "Simpson"); + Person person = new Person("36", "Homer", "Simpson", Kindness.Nice); repository.insert(person); @@ -201,7 +202,7 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC @Test // DATACASS-445 public void saveEntityShouldInsertPartialEntity() { - Person justId = new Person("foo", null, null); + Person justId = new Person("foo", null, null, Kindness.Nice); Person saved = repository.save(justId); assertThat(saved).isEqualTo(saved); @@ -215,7 +216,7 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC @Test // DATACASS-445 public void saveEntityShouldInsertNewEntity() { - Person person = new Person("36", "Homer", "Simpson"); + Person person = new Person("36", "Homer", "Simpson", Kindness.Nice); Person saved = repository.save(person); @@ -241,7 +242,7 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC @Test // DATACASS-445 public void saveIterableOfMixedEntitiesShouldInsertEntity() { - Person person = new Person("36", "Homer", "Simpson"); + Person person = new Person("36", "Homer", "Simpson", Kindness.Nice); dave.setFirstname("Hello, Dave"); dave.setLastname("Bowman");