diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraCustomConversions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraCustomConversions.java index f5bc88c82..ac58265cd 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraCustomConversions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraCustomConversions.java @@ -17,20 +17,15 @@ package org.springframework.data.cassandra.core.convert; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; +import java.util.Date; import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; +import java.util.function.Predicate; -import org.springframework.core.ResolvableType; -import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair; import org.springframework.data.cassandra.core.mapping.CassandraSimpleTypeHolder; -import org.springframework.data.cassandra.core.mapping.CassandraType; -import org.springframework.data.convert.WritingConverter; +import org.springframework.data.convert.Jsr310Converters; import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; /** * Value object to capture custom conversion. {@link CassandraCustomConversions} also act as factory for @@ -45,12 +40,6 @@ public class CassandraCustomConversions extends org.springframework.data.convert private static final List STORE_CONVERTERS; - /** - * Set of types that indicate usage of Cassandra's time type. Time is represented as long so we need to imply the type - * from an artificial simple type. - */ - private final static Set> NATIVE_TIME_TYPE_MARKERS; - private static final StoreConversions STORE_CONVERSIONS; static { @@ -64,25 +53,6 @@ public class CassandraCustomConversions extends org.springframework.data.convert STORE_CONVERTERS = Collections.unmodifiableList(converters); STORE_CONVERSIONS = StoreConversions.of(CassandraSimpleTypeHolder.HOLDER, STORE_CONVERTERS); - - List> timeMarkers = STORE_CONVERTERS.stream() // - .filter(Converter.class::isInstance) // - .map(Object::getClass) // - .filter(it -> AnnotatedElementUtils.hasAnnotation(it, WritingConverter.class)) // - .filter(it -> { - - CassandraType annotation = AnnotatedElementUtils.getMergedAnnotation(it, CassandraType.class); - - return annotation != null && annotation.type() == CassandraType.Name.TIME; - }) // - .map(it -> { - - ResolvableType classType = ResolvableType.forClass(it).as(Converter.class).getGeneric(0); - - return classType.getRawClass(); - }).collect(Collectors.toList()); - - NATIVE_TIME_TYPE_MARKERS = new HashSet<>(timeMarkers); } /** @@ -91,20 +61,36 @@ public class CassandraCustomConversions extends org.springframework.data.convert * @param converters must not be {@literal null}. */ public CassandraCustomConversions(List converters) { - super(STORE_CONVERSIONS, converters); + super(new CassandraConverterConfiguration(STORE_CONVERSIONS, converters)); } /** - * Returns {@literal true} if the {@link Class type} is used to denote Cassandra's {@code time} column type. - * - * @param type must not be {@literal null}. - * @return {@literal true} if the type maps to Cassandra's {@code time} column type. - * @since 2.1 + * Cassandra-specific extension to {@link org.springframework.data.convert.CustomConversions.ConverterConfiguration}. + * This extension avoids {@link Converter} registrations that enforce date mapping to {@link Date} from JSR-310, Joda + * Time and ThreeTenBackport. */ - public boolean isNativeTimeTypeMarker(Class type) { + static class CassandraConverterConfiguration extends ConverterConfiguration { - Assert.notNull(type, "Type must not be null"); + public CassandraConverterConfiguration(StoreConversions storeConversions, List userConverters) { + super(storeConversions, userConverters, getConverterFilter()); + } - return NATIVE_TIME_TYPE_MARKERS.contains(ClassUtils.getUserClass(type)); + static Predicate getConverterFilter() { + + return convertiblePair -> { + + if (sourceMatches(convertiblePair, "org.joda.time") || sourceMatches(convertiblePair, "org.threeten.bp") + || Jsr310Converters.supports(convertiblePair.getSourceType()) + && Date.class.isAssignableFrom(convertiblePair.getTargetType())) { + return false; + } + + return true; + }; + } + + private static boolean sourceMatches(ConvertiblePair convertiblePair, String packagePrefix) { + return convertiblePair.getSourceType().getName().startsWith(packagePrefix); + } } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraJodaTimeConverters.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraJodaTimeConverters.java index 133f7d1c7..62242fde1 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraJodaTimeConverters.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraJodaTimeConverters.java @@ -15,8 +15,6 @@ */ package org.springframework.data.cassandra.core.convert; -import static org.springframework.data.cassandra.core.mapping.CassandraType.*; - import java.sql.Date; import java.util.ArrayList; import java.util.Collection; @@ -24,12 +22,12 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; +import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; import org.springframework.core.convert.converter.Converter; -import org.springframework.data.cassandra.core.mapping.CassandraType; import org.springframework.data.convert.WritingConverter; import org.springframework.util.ClassUtils; @@ -74,6 +72,9 @@ public abstract class CassandraJodaTimeConverters { converters.add(LocalDateTimeToInstantConverter.INSTANCE); converters.add(InstantToLocalDateTimeConverter.INSTANCE); + converters.add(DateTimeToInstantConverter.INSTANCE); + converters.add(InstantToDateTimeConverter.INSTANCE); + return converters; } @@ -113,7 +114,6 @@ public abstract class CassandraJodaTimeConverters { * @author Mark Paluch */ @WritingConverter - @CassandraType(type = Name.TIME) public enum FromJodaLocalTimeConverter implements Converter { INSTANCE; @@ -145,7 +145,6 @@ public abstract class CassandraJodaTimeConverters { * @author Mark Paluch */ @WritingConverter - @CassandraType(type = Name.DATE) public enum FromJodaLocalDateConverter implements Converter { INSTANCE; @@ -176,7 +175,6 @@ public abstract class CassandraJodaTimeConverters { * * @since 3.0 */ - @WritingConverter public enum LocalDateTimeToInstantConverter implements Converter { INSTANCE; @@ -188,7 +186,7 @@ public abstract class CassandraJodaTimeConverters { } /** - * Simple singleton to convert {@link java.time.LocalDateTime}s to their {@link LocalDateTime} representation. + * Simple singleton to convert {@link java.time.Instant}s to their {@link LocalDateTime} representation. * * @since 3.0 */ @@ -201,4 +199,34 @@ public abstract class CassandraJodaTimeConverters { return new LocalDateTime(Date.from(source)); } } + + /** + * Simple singleton to convert {@link DateTime}s to their {@link java.time.Instant} representation. + * + * @since 3.0 + */ + public enum DateTimeToInstantConverter implements Converter { + + INSTANCE; + + @Override + public java.time.Instant convert(DateTime source) { + return source.toDate().toInstant(); + } + } + + /** + * Simple singleton to convert {@link java.time.Instant}s to their {@link DateTime} representation. + * + * @since 3.0 + */ + public enum InstantToDateTimeConverter implements Converter { + + INSTANCE; + + @Override + public DateTime convert(java.time.Instant source) { + return new DateTime(Date.from(source)); + } + } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraJsr310Converters.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraJsr310Converters.java index f9d314668..d468c1920 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraJsr310Converters.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraJsr310Converters.java @@ -18,7 +18,6 @@ package org.springframework.data.cassandra.core.convert; import static java.time.ZoneId.*; import java.time.Instant; -import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.temporal.ChronoField; @@ -58,10 +57,6 @@ public abstract class CassandraJsr310Converters { converters.add(DateToInstantConverter.INSTANCE); converters.add(LocalDateToInstantConverter.INSTANCE); - converters.add(LocalDateConverter.INSTANCE); - converters.add(LocalTimeConverter.INSTANCE); - converters.add(InstantConverter.INSTANCE); - return converters; } @@ -117,55 +112,7 @@ public abstract class CassandraJsr310Converters { } /** - * Force {@link LocalDate} to remain a {@link LocalDate}. - * - * @since 3.0 - */ - @WritingConverter - enum LocalDateConverter implements Converter { - - INSTANCE; - - @Override - public LocalDate convert(LocalDate source) { - return source; - } - } - - /** - * Force {@link LocalTime} to remain a {@link LocalTime}. - * - * @since 3.0 - */ - @WritingConverter - enum LocalTimeConverter implements Converter { - - INSTANCE; - - @Override - public LocalTime convert(LocalTime source) { - return source; - } - } - - /** - * Force {@link Instant} to remain a {@link Instant}. - * - * @since 3.0 - */ - @WritingConverter - enum InstantConverter implements Converter { - - INSTANCE; - - @Override - public Instant convert(Instant source) { - return source; - } - } - - /** - * Force {@link LocalDateTime} to remain a {@link Instant}. + * Converter from {@link LocalDateTime} to {@link Instant}. * * @since 3.0 */ diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraThreeTenBackPortConverters.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraThreeTenBackPortConverters.java index 3c7ae7dcb..c2ae3cad3 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraThreeTenBackPortConverters.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraThreeTenBackPortConverters.java @@ -15,8 +15,6 @@ */ package org.springframework.data.cassandra.core.convert; -import static org.springframework.data.cassandra.core.mapping.CassandraType.*; - import java.time.Instant; import java.util.ArrayList; import java.util.Collection; @@ -25,7 +23,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; import org.springframework.core.convert.converter.Converter; -import org.springframework.data.cassandra.core.mapping.CassandraType; import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.ThreeTenBackPortConverters; import org.springframework.data.convert.WritingConverter; @@ -82,6 +79,11 @@ public abstract class CassandraThreeTenBackPortConverters { converters.add(ToBpLocalDateTimeConverter.INSTANCE); converters.add(LocalDateTimeToInstantConverter.INSTANCE); + converters.add(BpInstantToInstantConverter.INSTANCE); + converters.add(InstantToBpInstantConverter.INSTANCE); + + converters.add(ZoneIdToStringConverter.INSTANCE); + converters.add(StringToZoneIdConverter.INSTANCE); return converters; } @@ -92,7 +94,6 @@ public abstract class CassandraThreeTenBackPortConverters { * @author Mark Paluch * @since 2.1 */ - @ReadingConverter public enum MillisOfDayToLocalTimeConverter implements Converter { INSTANCE; @@ -126,7 +127,6 @@ public abstract class CassandraThreeTenBackPortConverters { * @since 3.0 */ @WritingConverter - @CassandraType(type = Name.TIME) public enum FromBpLocalTimeConverter implements Converter { INSTANCE; @@ -142,7 +142,6 @@ public abstract class CassandraThreeTenBackPortConverters { * * @since 3.0 */ - @ReadingConverter public enum ToBpLocalTimeConverter implements Converter { INSTANCE; @@ -159,7 +158,6 @@ public abstract class CassandraThreeTenBackPortConverters { * @since 3.0 */ @WritingConverter - @CassandraType(type = Name.DATE) public enum FromBpLocalDateConverter implements Converter { INSTANCE; @@ -175,7 +173,6 @@ public abstract class CassandraThreeTenBackPortConverters { * * @since 3.0 */ - @ReadingConverter public enum ToBpLocalDateConverter implements Converter { INSTANCE; @@ -208,7 +205,6 @@ public abstract class CassandraThreeTenBackPortConverters { * * @since 3.0 */ - @ReadingConverter public enum ToBpLocalDateTimeConverter implements Converter { INSTANCE; @@ -221,11 +217,10 @@ public abstract class CassandraThreeTenBackPortConverters { } /** - * Force {@link LocalDateTime} to remain a {@link Instant}. + * Convert {@link LocalDateTime} to {@link Instant}. * * @since 3.0 */ - @WritingConverter enum LocalDateTimeToInstantConverter implements Converter { INSTANCE; @@ -235,4 +230,64 @@ public abstract class CassandraThreeTenBackPortConverters { return Instant.ofEpochMilli(source.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); } } + + /** + * Convert {@link org.threeten.bp.Instant} to {@link java.time.Instant}. + * + * @since 3.0 + */ + enum BpInstantToInstantConverter implements Converter { + + INSTANCE; + + @Override + public java.time.Instant convert(org.threeten.bp.Instant source) { + return Instant.ofEpochMilli(source.toEpochMilli()); + } + } + + /** + * Convert {@link java.time.Instant} to {@link org.threeten.bp.Instant}. + * + * @since 3.0 + */ + enum InstantToBpInstantConverter implements Converter { + + INSTANCE; + + @Override + public org.threeten.bp.Instant convert(java.time.Instant source) { + return org.threeten.bp.Instant.ofEpochMilli(source.toEpochMilli()); + } + } + + /** + * Convert {@link ZoneId} to {@link String}. + * + * @since 3.0 + */ + enum ZoneIdToStringConverter implements Converter { + + INSTANCE; + + @Override + public String convert(ZoneId source) { + return source.toString(); + } + } + + /** + * Convert {@link String} to {@link ZoneId}. + * + * @since 3.0 + */ + enum StringToZoneIdConverter implements Converter { + + INSTANCE; + + @Override + public ZoneId convert(String source) { + return ZoneId.of(source); + } + } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverter.java index f89e06423..77faf67cb 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverter.java @@ -92,25 +92,18 @@ public class MappingCassandraConverter extends AbstractCassandraConverter private SpELContext spELContext; - private static ConversionService newConversionService() { - return new DefaultConversionService(); - } - - private static CassandraMappingContext newDefaultMappingContext() { - - CassandraMappingContext mappingContext = new CassandraMappingContext(); - - mappingContext.setCustomConversions(new CassandraCustomConversions(Collections.emptyList())); - mappingContext.afterPropertiesSet(); - - return mappingContext; - } - /** * Create a new {@link MappingCassandraConverter} with a {@link CassandraMappingContext}. */ public MappingCassandraConverter() { - this(newDefaultMappingContext()); + + super(newConversionService()); + + CassandraCustomConversions conversions = new CassandraCustomConversions(Collections.emptyList()); + + this.mappingContext = newDefaultMappingContext(conversions); + this.setCustomConversions(conversions); + this.spELContext = new SpELContext(RowReaderPropertyAccessor.INSTANCE); } /** @@ -124,10 +117,25 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Assert.notNull(mappingContext, "CassandraMappingContext must not be null"); + this.setCustomConversions(mappingContext.getCustomConversions()); this.mappingContext = mappingContext; this.spELContext = new SpELContext(RowReaderPropertyAccessor.INSTANCE); } + private static ConversionService newConversionService() { + return new DefaultConversionService(); + } + + private static CassandraMappingContext newDefaultMappingContext(CassandraCustomConversions conversions) { + + CassandraMappingContext mappingContext = new CassandraMappingContext(); + + mappingContext.setCustomConversions(conversions); + mappingContext.afterPropertiesSet(); + + return mappingContext; + } + /* (non-Javadoc) * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) */ diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContext.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContext.java index 980c2aa77..29d0b2d0b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContext.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContext.java @@ -96,7 +96,7 @@ public class CassandraMappingContext * Create a new {@link CassandraMappingContext}. */ public CassandraMappingContext() { - setSimpleTypeHolder(CassandraSimpleTypeHolder.HOLDER); + setSimpleTypeHolder(customConversions.getSimpleTypeHolder()); } /** @@ -110,7 +110,7 @@ public class CassandraMappingContext setUserTypeResolver(userTypeResolver); setTupleTypeFactory(tupleTypeFactory); - setSimpleTypeHolder(CassandraSimpleTypeHolder.HOLDER); + setSimpleTypeHolder(customConversions.getSimpleTypeHolder()); } /* (non-Javadoc) @@ -200,6 +200,10 @@ public class CassandraMappingContext this.customConversions = customConversions; } + public CustomConversions getCustomConversions() { + return customConversions; + } + /** * Sets the {@link Mapping}. * @@ -557,7 +561,7 @@ public class CassandraMappingContext * @since 1.5 */ public DataType getDataType(Class type) { - return doGetDataType(type, this.customConversions.getCustomWriteTarget(type).orElse(type)); + return CassandraSimpleTypeHolder.getDataTypeFor(this.customConversions.getCustomWriteTarget(type).orElse(type)); } public TupleType getTupleType(CassandraPersistentEntity persistentEntity) { @@ -651,7 +655,10 @@ public class CassandraMappingContext Supplier fallback) { Optional customWriteTarget = this.customConversions.getCustomWriteTarget(typeInformation.getType()) - .map(it -> doGetDataType(typeInformation.getType(), it)); + .map(it -> { + typeInformation.getType(); + return CassandraSimpleTypeHolder.getDataTypeFor(it); + }); DataType dataType = customWriteTarget.orElseGet(() -> { @@ -662,15 +669,15 @@ public class CassandraMappingContext if (typeInformation.isCollectionLike()) { if (List.class.isAssignableFrom(typeInformation.getType())) { - return DataTypes.listOf(doGetDataType(propertyType, it)); + return DataTypes.listOf(CassandraSimpleTypeHolder.getDataTypeFor(it)); } if (Set.class.isAssignableFrom(typeInformation.getType())) { - return DataTypes.setOf(doGetDataType(propertyType, it)); + return DataTypes.setOf(CassandraSimpleTypeHolder.getDataTypeFor(it)); } } - return doGetDataType(propertyType, it); + return CassandraSimpleTypeHolder.getDataTypeFor(it); }).orElse(null); }); @@ -718,7 +725,7 @@ public class CassandraMappingContext return dataTypeProvider.getDataType(persistentEntity); } - DataType determinedType = doGetDataType(typeInformation); + DataType determinedType = CassandraSimpleTypeHolder.getDataTypeFor(typeInformation.getType()); if (determinedType != null) { return determinedType; @@ -727,41 +734,6 @@ public class CassandraMappingContext return fallback.get(); } - /** - * Resolve Cassandra {@link DataType}. - * - * @param typeInformation - * @return - */ - @Nullable - private DataType doGetDataType(TypeInformation typeInformation) { - return doGetDataType(typeInformation.getType(), typeInformation.getType()); - } - - /** - * Resolve Cassandra {@link DataType} with conditional handling of {@code time} data type. - * - * @param propertyType - * @param converted - * @return - */ - @Nullable - private DataType doGetDataType(Class propertyType, Class converted) { - - if (this.customConversions instanceof CassandraCustomConversions) { - - CassandraCustomConversions conversions = (CassandraCustomConversions) this.customConversions; - - if (conversions.isNativeTimeTypeMarker(converted) - || (conversions.isNativeTimeTypeMarker(propertyType) && Long.class.equals(converted))) { - - return DataTypes.TIME; - } - } - - return CassandraSimpleTypeHolder.getDataTypeFor(converted); - } - private TupleType getTupleType(DataTypeProvider dataTypeProvider, CassandraPersistentEntity persistentEntity) { List types = new ArrayList<>(); @@ -781,7 +753,8 @@ public class CassandraMappingContext DataType keyType = getDataTypeWithUserTypeFactory(keyTypeInformation, dataTypeProvider, () -> { - DataType type = doGetDataType(keyTypeInformation.getType(), keyTypeInformation.getType()); + keyTypeInformation.getType(); + DataType type = CassandraSimpleTypeHolder.getDataTypeFor(keyTypeInformation.getType()); if (type != null) { return type; @@ -792,7 +765,8 @@ public class CassandraMappingContext DataType valueType = getDataTypeWithUserTypeFactory(valueTypeInformation, dataTypeProvider, () -> { - DataType type = doGetDataType(valueTypeInformation.getType(), valueTypeInformation.getType()); + valueTypeInformation.getType(); + DataType type = CassandraSimpleTypeHolder.getDataTypeFor(valueTypeInformation.getType()); if (type != null) { return type; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/CassandraTypeMappingIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/CassandraTypeMappingIntegrationTests.java index 6622ecffa..c2387da0c 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/CassandraTypeMappingIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/CassandraTypeMappingIntegrationTests.java @@ -56,6 +56,7 @@ import org.springframework.data.util.Version; import com.datastax.oss.driver.api.core.cql.ResultSet; import com.datastax.oss.driver.api.core.cql.Row; import com.datastax.oss.driver.api.core.cql.SimpleStatement; +import com.datastax.oss.driver.api.core.data.CqlDuration; import com.datastax.oss.driver.api.core.data.TupleValue; import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.TupleType; @@ -522,13 +523,13 @@ public class CassandraTypeMappingIntegrationTests extends AbstractKeyspaceCreati AllPossibleTypes entity = new AllPossibleTypes("1"); - entity.setLocalDate(java.time.LocalDate.of(2010, 7, 4)); + entity.setDate(java.time.LocalDate.of(2010, 7, 4)); operations.insert(entity); AllPossibleTypes loaded = load(entity); - assertThat(loaded.getLocalDate()).isEqualTo(entity.getLocalDate()); + assertThat(loaded.getDate()).isEqualTo(entity.getDate()); } @Test // DATACASS-296 @@ -552,42 +553,42 @@ public class CassandraTypeMappingIntegrationTests extends AbstractKeyspaceCreati AllPossibleTypes entity = new AllPossibleTypes("1"); - entity.setLocalTime(java.time.LocalTime.of(1, 2, 3)); + entity.setTime(java.time.LocalTime.of(1, 2, 3)); operations.insert(entity); AllPossibleTypes loaded = load(entity); - assertThat(loaded.getLocalTime()).isEqualTo(entity.getLocalTime()); + assertThat(loaded.getTime()).isEqualTo(entity.getTime()); } - @Test // DATACASS-694 + @Test // DATACASS-694, DATACASS-727 public void shouldReadLocalTimeFromDriver() { assumeTrue(cassandraVersion.isGreaterThanOrEqualTo(VERSION_3_10)); AllPossibleTypes entity = new AllPossibleTypes("1"); - entity.setLocalTime(java.time.LocalTime.of(1, 2, 3)); + entity.setTime(java.time.LocalTime.of(1, 2, 3)); operations.insert(entity); - ResultSet resultSet = session.execute("SELECT localTime FROM AllPossibleTypes WHERE id = '1'"); + ResultSet resultSet = session.execute("SELECT time FROM AllPossibleTypes WHERE id = '1'"); Row row = resultSet.one(); - assertThat(row.getLocalTime(0)).isEqualTo(entity.getLocalTime()); + assertThat(row.getLocalTime(0)).isEqualTo(entity.getTime()); } - @Test // DATACASS-694 + @Test // DATACASS-694, DATACASS-727 public void shouldWriteLocalTimeThroughDriver() { assumeTrue(cassandraVersion.isGreaterThanOrEqualTo(VERSION_3_10)); - session.execute("INSERT INTO AllPossibleTypes(id,localTime) VALUES('1','01:02:03.000')"); + session.execute("INSERT INTO AllPossibleTypes(id,time) VALUES('1','01:02:03.000')"); - AllPossibleTypes entity = operations.selectOne("SELECT localTime FROM AllPossibleTypes WHERE id = '1'", + AllPossibleTypes entity = operations.selectOne("SELECT time FROM AllPossibleTypes WHERE id = '1'", AllPossibleTypes.class); - assertThat(entity.getLocalTime()).isEqualTo(LocalTime.of(1, 2, 3, 0)); + assertThat(entity.getTime()).isEqualTo(LocalTime.of(1, 2, 3, 0)); } @Test // DATACASS-296, DATACASS-563 @@ -649,8 +650,7 @@ public class CassandraTypeMappingIntegrationTests extends AbstractKeyspaceCreati assertThat(loaded.getJodaLocalDate()).isEqualTo(entity.getJodaLocalDate()); } - @Test // DATACASS-296 - @Ignore("DATACASS-656 - Custom Conversions lookup order") + @Test // DATACASS-296, DATACASS-727 public void shouldReadAndWriteJodaDateTime() { AllPossibleTypes entity = new AllPossibleTypes("1"); @@ -708,8 +708,7 @@ public class CassandraTypeMappingIntegrationTests extends AbstractKeyspaceCreati assertThat(loaded.getBpLocalTime()).isEqualTo(entity.getBpLocalTime()); } - @Test // DATACASS-296 - @Ignore("DATACASS-656 - Custom Conversions lookup order") + @Test // DATACASS-296, DATACASS-727 public void shouldReadAndWriteBpInstant() { AllPossibleTypes entity = new AllPossibleTypes("1"); @@ -752,18 +751,19 @@ public class CassandraTypeMappingIntegrationTests extends AbstractKeyspaceCreati assertThat(loaded.getCount()).isEqualTo(entity.getCount()); } - @Test // DATACASS-429 + @Test // DATACASS-429, DATACASS-727 public void shouldReadAndWriteDuration() { assumeTrue(cassandraVersion.isGreaterThanOrEqualTo(VERSION_3_10)); - WithDuration withDuration = new WithDuration("foo", Duration.ofHours(2)); + WithDuration withDuration = new WithDuration("foo", Duration.ofHours(2), CqlDuration.newInstance(1, 2, 3)); operations.insert(withDuration); WithDuration loaded = operations.selectOneById(withDuration.getId(), WithDuration.class); assertThat(loaded.getDuration()).isEqualTo(withDuration.getDuration()); + assertThat(loaded.getCqlDuration()).isEqualTo(withDuration.getCqlDuration()); } private AllPossibleTypes load(AllPossibleTypes entity) { @@ -780,6 +780,7 @@ public class CassandraTypeMappingIntegrationTests extends AbstractKeyspaceCreati @Id String id; Duration duration; + CqlDuration cqlDuration; } @Data diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverterUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverterUnitTests.java index b3efe706b..d63c0a5d6 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverterUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverterUnitTests.java @@ -37,7 +37,6 @@ import java.time.ZoneOffset; import java.util.*; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.springframework.data.annotation.Id; @@ -341,8 +340,7 @@ public class MappingCassandraConverterUnitTests { assertThat(insert.get(CqlIdentifier.fromCql("timestamp"))).isInstanceOf(Instant.class); } - @Test // DATACASS-656 - @Ignore("Fails because of reverse custom conversion registration order") + @Test // DATACASS-656, DATACASS-727 public void shouldReadAndWriteTimestampFromObjectWithConversion() { AllPossibleTypes entity = new AllPossibleTypes("1"); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContextUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContextUnitTests.java index f6468e069..5064a4c0a 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContextUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContextUnitTests.java @@ -487,7 +487,7 @@ public class CassandraMappingContextUnitTests { CassandraPersistentEntity persistentEntity = mappingContext.getRequiredPersistentEntity(AllPossibleTypes.class); - assertThat(mappingContext.getDataType(persistentEntity.getRequiredPersistentProperty("localTime"))) + assertThat(mappingContext.getDataType(persistentEntity.getRequiredPersistentProperty("time"))) .isEqualTo(DataTypes.TIME); assertThat(mappingContext.getDataType(persistentEntity.getRequiredPersistentProperty("jodaLocalTime"))) .isEqualTo(DataTypes.TIME); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java index 9251f143b..e95ed9118 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java @@ -210,7 +210,6 @@ public class CreateTableSpecificationBasicCassandraMappingContextUnitTests { CreateTableSpecification specification = getCreateTableSpecificationFor(AllPossibleTypes.class); assertThat(getColumnType("date", specification)).isEqualTo(DataTypes.DATE); - assertThat(getColumnType("localDate", specification)).isEqualTo(DataTypes.DATE); assertThat(getColumnType("jodaLocalDate", specification)).isEqualTo(DataTypes.DATE); assertThat(getColumnType("bpLocalDate", specification)).isEqualTo(DataTypes.DATE); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/domain/AllPossibleTypes.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/domain/AllPossibleTypes.java index a2bf07198..de1b5b770 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/domain/AllPossibleTypes.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/domain/AllPossibleTypes.java @@ -26,7 +26,6 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.nio.ByteBuffer; -import java.time.LocalDate; import java.util.Date; import java.util.List; import java.util.Map; @@ -78,7 +77,9 @@ public class AllPossibleTypes { Boolean boxedBoolean; boolean primitiveBoolean; - LocalDate date; + java.time.Instant instant; + java.time.LocalDate date; + java.time.LocalTime time; Date timestamp; @@ -97,10 +98,7 @@ public class AllPossibleTypes { @CassandraType(type = Name.TUPLE, typeArguments = { Name.VARCHAR, Name.BIGINT }) TupleValue tupleValue; // supported by conversion - java.time.Instant instant; - java.time.LocalDate localDate; java.time.LocalDateTime localDateTime; - java.time.LocalTime localTime; java.time.ZoneId zoneId; org.joda.time.DateTime jodaDateTime; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryQueryMethodParameterTypesIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryQueryMethodParameterTypesIntegrationTests.java index f292e309f..03d62262d 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryQueryMethodParameterTypesIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryQueryMethodParameterTypesIntegrationTests.java @@ -93,16 +93,16 @@ public class RepositoryQueryMethodParameterTypesIntegrationTests @Test // DATACASS-296 public void shouldFindByLocalDate() { - session.execute("CREATE INDEX IF NOT EXISTS allpossibletypes_localdate ON allpossibletypes ( localdate )"); + session.execute("CREATE INDEX IF NOT EXISTS allpossibletypes_localdate ON allpossibletypes ( date )"); AllPossibleTypes allPossibleTypes = new AllPossibleTypes(); allPossibleTypes.setId("id"); - allPossibleTypes.setLocalDate(LocalDate.now()); + allPossibleTypes.setDate(LocalDate.now()); allPossibleTypesRepository.save(allPossibleTypes); - List result = allPossibleTypesRepository.findWithCreatedDate(allPossibleTypes.getLocalDate()); + List result = allPossibleTypesRepository.findWithCreatedDate(allPossibleTypes.getDate()); assertThat(result).hasSize(1); assertThat(result).contains(allPossibleTypes); @@ -182,7 +182,7 @@ public class RepositoryQueryMethodParameterTypesIntegrationTests private interface AllPossibleTypesRepository extends CrudRepository { - @Query("select * from allpossibletypes where localdate = ?0") + @Query("select * from allpossibletypes where date = ?0") List findWithCreatedDate(java.time.LocalDate createdDate); @Query("select * from allpossibletypes where zoneid = ?0")