From 1c824f2965b869dd4b1c61b8b63dc9d3b85a2a06 Mon Sep 17 00:00:00 2001 From: John Blum Date: Wed, 29 Jun 2016 14:44:36 -0700 Subject: [PATCH] DATACASS-296 - Polish. Original pull request: #68. --- .../java/AbstractCassandraConfiguration.java | 54 ++++----- .../convert/CassandraConverters.java | 15 +-- .../convert/CassandraJodaTimeConverters.java | 10 +- .../convert/CassandraJsr310Converters.java | 7 +- .../CassandraThreeTenBackPortConverters.java | 10 +- .../cassandra/convert/CustomConversions.java | 9 +- .../mapping/BasicCassandraMappingContext.java | 105 ++++++++---------- .../BasicCassandraPersistentEntity.java | 40 +++---- .../BasicCassandraPersistentProperty.java | 26 +++-- .../query/CassandraQueryMethod.java | 26 +++-- .../query/ConvertingParameterAccessor.java | 2 +- .../query/StringBasedCassandraQuery.java | 15 ++- .../MappingCassandraConverterUnitTests.java | 74 ++++++++---- .../cassandra/domain/AllPossibleTypes.java | 2 - .../mapping/MappingContextUnitTests.java | 40 ++++--- ...yMethodParameterTypesIntegrationTests.java | 11 +- .../config/SchemaActionIntegrationTests.java | 13 ++- 17 files changed, 247 insertions(+), 212 deletions(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractCassandraConfiguration.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractCassandraConfiguration.java index b0efd5edf..8d80f094a 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractCassandraConfiguration.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractCassandraConfiguration.java @@ -1,12 +1,12 @@ /* * Copyright 2013-2016 the original author or authors - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -37,7 +37,7 @@ import org.springframework.data.mapping.context.MappingContext; /** * Base class for Spring Data Cassandra configuration using JavaConfig. - * + * * @author Alex Shvid * @author Matthew T. Adams * @author John Blum @@ -65,24 +65,22 @@ public abstract class AbstractCassandraConfiguration extends AbstractClusterConf } /** - * Return the {@link MappingContext} instance to map Entities to properties. + * Creates a {@link CassandraConverter} using the configured {@link #cassandraMapping()}. + * Will apply all specified {@link #customConversions()}. * - * @throws ClassNotFoundException + * @return {@link CassandraConverter} used to convert Java and Cassandra value types during the mapping process. + * @throws Exception if an error occurs initializing or registering the converter. + * @see #cassandraMapping() + * @see #customConversions() */ @Bean - public CassandraMappingContext cassandraMapping() throws ClassNotFoundException { + public CassandraConverter cassandraConverter() throws Exception { - BasicCassandraMappingContext mappingContext = new BasicCassandraMappingContext(); + MappingCassandraConverter mappingCassandraConverter = new MappingCassandraConverter(cassandraMapping()); - mappingContext.setBeanClassLoader(beanClassLoader); - mappingContext.setInitialEntitySet(CassandraEntityClassScanner.scan(getEntityBasePackages())); + mappingCassandraConverter.setCustomConversions(customConversions()); - CustomConversions customConversions = customConversions(); - - mappingContext.setCustomConversions(customConversions); - mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder()); - - return mappingContext; + return mappingCassandraConverter; } /** @@ -99,22 +97,26 @@ public abstract class AbstractCassandraConfiguration extends AbstractClusterConf } /** - * Creates a {@link CassandraConverter} using the configured {@link #cassandraMapping()}. Will get - * {@link #customConversions()} applied. + * Return the {@link MappingContext} instance to map Entities to properties. * - * @see #customConversions() - * @see #cassandraMapping() - * @return - * @throws Exception + * @throws ClassNotFoundException if the Cassandra Entity class type identified by name + * cannot be found during the scan. + * @see CassandraMappingContext */ @Bean - public CassandraConverter cassandraConverter() throws Exception { + public CassandraMappingContext cassandraMapping() throws ClassNotFoundException { - MappingCassandraConverter mappingCassandraConverter = new MappingCassandraConverter(cassandraMapping()); + BasicCassandraMappingContext mappingContext = new BasicCassandraMappingContext(); - mappingCassandraConverter.setCustomConversions(customConversions()); + mappingContext.setBeanClassLoader(beanClassLoader); + mappingContext.setInitialEntitySet(CassandraEntityClassScanner.scan(getEntityBasePackages())); - return mappingCassandraConverter; + CustomConversions customConversions = customConversions(); + + mappingContext.setCustomConversions(customConversions); + mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder()); + + return mappingContext; } /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverters.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverters.java index 6400d06dd..8d7f96055 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverters.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverters.java @@ -49,22 +49,20 @@ abstract class CassandraConverters { /** * Returns the converters to be registered. - * - * @return */ public static Collection getConvertersToRegister() { List converters = new ArrayList(); converters.add(RowToCassandraLocalDateConverter.INSTANCE); - converters.add(RowToNumberConverterFactory.INSTANCE); converters.add(RowToBooleanConverter.INSTANCE); converters.add(RowToDateConverter.INSTANCE); converters.add(RowToInetAddressConverter.INSTANCE); - converters.add(RowToStringConverter.INSTANCE); - converters.add(RowToUuidConverter.INSTANCE); converters.add(RowToListConverter.INSTANCE); converters.add(RowToMapConverter.INSTANCE); + converters.add(RowToNumberConverterFactory.INSTANCE); + converters.add(RowToStringConverter.INSTANCE); + converters.add(RowToUuidConverter.INSTANCE); return converters; } @@ -90,7 +88,6 @@ abstract class CassandraConverters { @Override public Date convert(Row row) { - return row.getTimestamp(0); } } @@ -148,11 +145,9 @@ abstract class CassandraConverters { public T convert(Row source) { Object object = source.getObject(0); - if (object == null) { - return null; - } - return NumberUtils.convertNumberToTargetClass((Number) object, this.targetType); + return (object != null ? NumberUtils.convertNumberToTargetClass((Number) object, this.targetType) + : null); } } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraJodaTimeConverters.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraJodaTimeConverters.java index b7adec039..4d672f2f0 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraJodaTimeConverters.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraJodaTimeConverters.java @@ -51,9 +51,9 @@ public abstract class CassandraJodaTimeConverters { } List> converters = new ArrayList>(); + converters.add(CassandraLocalDateToLocalDateConverter.INSTANCE); converters.add(LocalDateToCassandraLocalDateConverter.INSTANCE); - converters.add(CassandraLocalDateToDateMidnightConverter.INSTANCE); converters.add(DateMidnightToCassandraLocalDateConverter.INSTANCE); @@ -65,7 +65,7 @@ public abstract class CassandraJodaTimeConverters { * * @author Mark Paluch */ - public static enum CassandraLocalDateToLocalDateConverter + public enum CassandraLocalDateToLocalDateConverter implements Converter { INSTANCE; @@ -81,7 +81,7 @@ public abstract class CassandraJodaTimeConverters { * * @author Mark Paluch */ - public static enum LocalDateToCassandraLocalDateConverter + public enum LocalDateToCassandraLocalDateConverter implements Converter { INSTANCE; @@ -99,7 +99,7 @@ public abstract class CassandraJodaTimeConverters { * * @author Mark Paluch */ - public static enum CassandraLocalDateToDateMidnightConverter + public enum CassandraLocalDateToDateMidnightConverter implements Converter { INSTANCE; @@ -116,7 +116,7 @@ public abstract class CassandraJodaTimeConverters { * * @author Mark Paluch */ - public static enum DateMidnightToCassandraLocalDateConverter + public enum DateMidnightToCassandraLocalDateConverter implements Converter { INSTANCE; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraJsr310Converters.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraJsr310Converters.java index aa31617f6..05fafa848 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraJsr310Converters.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraJsr310Converters.java @@ -52,6 +52,7 @@ public abstract class CassandraJsr310Converters { } List> converters = new ArrayList>(); + converters.add(CassandraLocalDateToLocalDateConverter.INSTANCE); converters.add(LocalDateToCassandraLocalDateConverter.INSTANCE); @@ -60,10 +61,10 @@ public abstract class CassandraJsr310Converters { /** * Simple singleton to convert {@link com.datastax.driver.core.LocalDate}s to their {@link LocalDate} representation. - * + * * @author Mark Paluch */ - public static enum CassandraLocalDateToLocalDateConverter + public enum CassandraLocalDateToLocalDateConverter implements Converter { INSTANCE; @@ -79,7 +80,7 @@ public abstract class CassandraJsr310Converters { * * @author Mark Paluch */ - public static enum LocalDateToCassandraLocalDateConverter + public enum LocalDateToCassandraLocalDateConverter implements Converter { INSTANCE; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraThreeTenBackPortConverters.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraThreeTenBackPortConverters.java index ad78fa5e5..d260c6892 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraThreeTenBackPortConverters.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraThreeTenBackPortConverters.java @@ -18,17 +18,12 @@ package org.springframework.data.cassandra.convert; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.ThreeTenBackPortConverters; import org.springframework.util.ClassUtils; -import org.threeten.bp.Instant; import org.threeten.bp.LocalDate; -import org.threeten.bp.LocalDateTime; -import org.threeten.bp.ZoneId; /** * Helper class to register {@link Converter} implementations for the ThreeTen Backport project in case it's present on @@ -58,6 +53,7 @@ public abstract class CassandraThreeTenBackPortConverters { } List> converters = new ArrayList>(); + converters.add(CassandraLocalDateToLocalDateConverter.INSTANCE); converters.add(LocalDateToCassandraLocalDateConverter.INSTANCE); @@ -69,7 +65,7 @@ public abstract class CassandraThreeTenBackPortConverters { * * @author Mark Paluch */ - public static enum CassandraLocalDateToLocalDateConverter + public enum CassandraLocalDateToLocalDateConverter implements Converter { INSTANCE; @@ -85,7 +81,7 @@ public abstract class CassandraThreeTenBackPortConverters { * * @author Mark Paluch */ - public static enum LocalDateToCassandraLocalDateConverter + public enum LocalDateToCassandraLocalDateConverter implements Converter { INSTANCE; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java index 414998163..1e46c1a97 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java @@ -180,16 +180,17 @@ public class CustomConversions { private void registerConversion(Object converter) { Class type = converter.getClass(); - boolean isWriting = type.isAnnotationPresent(WritingConverter.class); + boolean isReading = type.isAnnotationPresent(ReadingConverter.class); + boolean isWriting = type.isAnnotationPresent(WritingConverter.class); if (converter instanceof GenericConverter) { GenericConverter genericConverter = (GenericConverter) converter; + for (ConvertiblePair pair : genericConverter.getConvertibleTypes()) { register(new ConverterRegistration(pair, isReading, isWriting)); } } else if (converter instanceof ConverterFactory) { - Class[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), ConverterFactory.class); register(new ConverterRegistration(arguments[0], arguments[1], isReading, isWriting)); } else if (converter instanceof Converter) { @@ -354,6 +355,7 @@ public class CustomConversions { for (ConvertiblePair typePair : pairs) { if (typePair.getSourceType().isAssignableFrom(sourceType)) { Class targetType = typePair.getTargetType(); + if (requestedTargetType == null || targetType.isAssignableFrom(requestedTargetType)) { return targetType; } @@ -381,7 +383,8 @@ public class CustomConversions { } Class type = producer.get(); - cache.put(key, CacheValue.> ofNullable(type)); + + cache.put(key, CacheValue.>ofNullable(type)); return type; } 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 65e4ed1d8..078413dcc 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 @@ -56,6 +56,7 @@ import com.datastax.driver.core.TableMetadata; * @author Alex Shvid * @author Matthew T. Adams * @author Mark Paluch + * @author John Blum */ public class BasicCassandraMappingContext extends AbstractMappingContext, CassandraPersistentProperty> @@ -89,7 +90,7 @@ public class BasicCassandraMappingContext /** * Sets the {@link CustomConversions}. - * + * * @param customConversions must not be {@literal null}. * @since 1.5 */ @@ -157,10 +158,10 @@ public class BasicCassandraMappingContext if (entities == null) { entities = new HashSet>(); + entitySetsByTableName.put(entity.getTableName(), entities); } entities.add(entity); - entitySetsByTableName.put(entity.getTableName(), entities); if (entity.isCompositePrimaryKey()) { primaryKeyEntities.add(entity); @@ -193,11 +194,11 @@ public class BasicCassandraMappingContext entity.doWithProperties(new PropertyHandler() { @Override - public void doWithPersistentProperty(CassandraPersistentProperty prop) { + public void doWithPersistentProperty(CassandraPersistentProperty property) { - if (prop.isCompositePrimaryKey()) { + if (property.isCompositePrimaryKey()) { - CassandraPersistentEntity pkEntity = getPersistentEntity(prop.getRawType()); + CassandraPersistentEntity pkEntity = getPersistentEntity(property.getRawType()); pkEntity.doWithProperties(new PropertyHandler() { @@ -213,12 +214,12 @@ public class BasicCassandraMappingContext }); } else { - if (prop.isIdProperty() || prop.isPartitionKeyColumn()) { - spec.partitionKeyColumn(prop.getColumnName(), getDataType(prop)); - } else if (prop.isClusterKeyColumn()) { - spec.clusteredKeyColumn(prop.getColumnName(), getDataType(prop)); + if (property.isIdProperty() || property.isPartitionKeyColumn()) { + spec.partitionKeyColumn(property.getColumnName(), getDataType(property)); + } else if (property.isClusterKeyColumn()) { + spec.clusteredKeyColumn(property.getColumnName(), getDataType(property)); } else { - spec.column(prop.getColumnName(), getDataType(prop)); + spec.column(property.getColumnName(), getDataType(property)); } } } @@ -236,13 +237,10 @@ public class BasicCassandraMappingContext * @see org.springframework.data.mapping.context.AbstractMappingContext#shouldCreatePersistentEntityFor(org.springframework.data.util.TypeInformation) */ @Override - protected boolean shouldCreatePersistentEntityFor(TypeInformation type) { + protected boolean shouldCreatePersistentEntityFor(TypeInformation typeInfo) { - if (customConversions.hasCustomWriteTarget(type.getType())) { - return false; - } - - return super.shouldCreatePersistentEntityFor(type); + return (!customConversions.hasCustomWriteTarget(typeInfo.getType()) + && super.shouldCreatePersistentEntityFor(typeInfo)); } /* (non-Javadoc) @@ -252,11 +250,7 @@ public class BasicCassandraMappingContext protected CassandraPersistentEntity addPersistentEntity(TypeInformation typeInformation) { // Prevent conversion types created as CassandraPersistentEntity - if (shouldCreatePersistentEntityFor(typeInformation)) { - return super.addPersistentEntity(typeInformation); - } - - return null; + return (shouldCreatePersistentEntityFor(typeInformation) ? super.addPersistentEntity(typeInformation) : null); } /* (non-Javadoc) @@ -301,55 +295,51 @@ public class BasicCassandraMappingContext @Override public DataType getDataType(Class type) { - if (customConversions.hasCustomWriteTarget(type)) { - return getDataTypeFor(customConversions.getCustomWriteTarget(type)); - } - - return getDataTypeFor(type); + return (customConversions.hasCustomWriteTarget(type) + ? getDataTypeFor(customConversions.getCustomWriteTarget(type)) + : getDataTypeFor(type)); } public void setMapping(Mapping mapping) { - Assert.notNull(mapping); + Assert.notNull(mapping, "Mapping must not be null"); this.mapping = mapping; } protected void processMappingOverrides() { - if (mapping == null) { - return; - } + if (mapping != null) { + for (EntityMapping entityMapping : mapping.getEntityMappings()) { - for (EntityMapping entityMapping : mapping.getEntityMappings()) { + if (entityMapping == null) { + continue; + } - if (entityMapping == null) { - continue; + String entityClassName = entityMapping.getEntityClassName(); + + try { + Class entityClass = ClassUtils.forName(entityClassName, beanClassLoader); + + CassandraPersistentEntity entity = getPersistentEntity(entityClass); + + if (entity == null) { + throw new IllegalStateException(String.format("unknown persistent entity class name [%s]", entityClassName)); + } + + String tableName = entityMapping.getTableName(); + + if (StringUtils.hasText(tableName)) { + entity.setTableName(cqlId(tableName, Boolean.valueOf(entityMapping.getForceQuote()))); + } + + processMappingOverrides(entity, entityMapping); + + } catch (ClassNotFoundException e) { + throw new IllegalStateException(String.format( + "unknown persistent entity name [%s]", entityClassName), e); + } } - - String entityClassName = entityMapping.getEntityClassName(); - - Class entityClass; - - try { - entityClass = ClassUtils.forName(entityClassName, beanClassLoader); - } catch (ClassNotFoundException e) { - throw new IllegalStateException(String.format("unknown persistent entity name [%s]", entityClassName), e); - } - - CassandraPersistentEntity entity = getPersistentEntity(entityClass); - - if (entity == null) { - throw new IllegalStateException(String.format("unknown persistent entity class name [%s]", entityClassName)); - } - - String tableName = entityMapping.getTableName(); - - if (StringUtils.hasText(tableName)) { - entity.setTableName(cqlId(tableName, Boolean.valueOf(entityMapping.getForceQuote()))); - } - - processMappingOverrides(entity, entityMapping); } } @@ -408,6 +398,7 @@ public class BasicCassandraMappingContext /** * @return Returns the verifier. */ + @SuppressWarnings("unused") public CassandraPersistentEntityMetadataVerifier getVerifier() { return verifier; } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java index eefa2c7d2..fbb4e9a1b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java @@ -1,12 +1,12 @@ /* * Copyright 2013-2014 the original author or authors - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -40,12 +40,13 @@ import org.springframework.util.StringUtils; /** * Cassandra specific {@link BasicPersistentEntity} implementation that adds Cassandra specific metadata. - * + * * @author Alex Shvid * @author Matthew T. Adams + * @author John Blum */ -public class BasicCassandraPersistentEntity extends BasicPersistentEntity implements - CassandraPersistentEntity, ApplicationContextAware { +public class BasicCassandraPersistentEntity extends BasicPersistentEntity + implements CassandraPersistentEntity, ApplicationContextAware { protected static final CassandraPersistentEntityMetadataVerifier DEFAULT_VERIFIER = new BasicCassandraPersistentEntityMetadataVerifier(); @@ -63,7 +64,7 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity typeInformation, CassandraMappingContext mappingContext) { @@ -74,7 +75,7 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity typeInformation, CassandraMappingContext mappingContext, @@ -89,13 +90,14 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity getCompositePrimaryKeyProperties() { - final List properties = new ArrayList(); + List properties = new ArrayList(); if (!isCompositePrimaryKey()) { - throw new IllegalStateException(String.format("[%s] does not represent a composite primary key class", this - .getType().getName())); + throw new IllegalStateException(String.format("[%s] does not represent a composite primary key class", + this.getType().getName())); } addCompositePrimaryKeyProperties(this, properties); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java index 860380ce1..387b4bead 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java @@ -56,7 +56,11 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP implements CassandraPersistentProperty, ApplicationContextAware { protected ApplicationContext context; - protected StandardEvaluationContext spelContext; + + /** + * Whether this property has been explicitly instructed to force quote column names. + */ + protected Boolean forceQuote; /** * An unmodifiable list of this property's column names. @@ -68,10 +72,7 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP */ protected List explicitColumnNames; - /** - * Whether this property has been explicitly instructed to force quote column names. - */ - protected Boolean forceQuote; + protected StandardEvaluationContext spelContext; /** * Creates a new {@link BasicCassandraPersistentProperty}. @@ -178,6 +179,7 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP if (isCollectionLike()) { List> args = getTypeInformation().getTypeArguments(); + ensureTypeArguments(args.size(), 1); if (Set.class.isAssignableFrom(getType())) { @@ -273,9 +275,7 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP @Override public List getColumnNames() { - if (columnNames == null) { - columnNames = Collections.unmodifiableList(determineColumnNames()); - } + columnNames = (columnNames != null ? columnNames : Collections.unmodifiableList(determineColumnNames())); return columnNames; } @@ -319,7 +319,7 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP String name = defaultName; if (StringUtils.hasText(overriddenName)) { - name = spelContext == null ? overriddenName : SpelUtils.evaluate(overriddenName, spelContext); + name = (spelContext == null ? overriddenName : SpelUtils.evaluate(overriddenName, spelContext)); } return cqlId(name, forceQuote); @@ -362,8 +362,8 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP columnNames.size())); } - this.columnNames = this.explicitColumnNames = Collections - .unmodifiableList(new ArrayList(columnNames)); + this.columnNames = this.explicitColumnNames = + Collections.unmodifiableList(new ArrayList(columnNames)); } @Override @@ -399,9 +399,11 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP @Override public CassandraPersistentEntity getCompositePrimaryKeyEntity() { CassandraMappingContext mappingContext = getOwner().getMappingContext(); + if (mappingContext == null) { - throw new IllegalStateException("need CassandraMappingContext"); + throw new IllegalStateException("CassandraMappingContext needed"); } + return mappingContext.getPersistentEntity(getCompositePrimaryKeyTypeInformation()); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java index f9a79295a..be295f771 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java @@ -41,12 +41,17 @@ import com.datastax.driver.core.ResultSet; */ public class CassandraQueryMethod extends QueryMethod { - private final Method method; - private final CassandraMappingContext mappingContext; - private Query query; - private String queryString; private boolean queryCached = false; + @SuppressWarnings("all") + private final CassandraMappingContext mappingContext; + + private final Method method; + + private Query query; + + private String queryString; + /** * Creates a new {@link CassandraQueryMethod} from the given {@link Method}. * @@ -60,7 +65,7 @@ public class CassandraQueryMethod extends QueryMethod { super(method, metadata, factory); - Assert.notNull(mappingContext, "MappingContext must not be null!"); + Assert.notNull(mappingContext, "MappingContext must not be null"); verify(method, metadata); @@ -68,11 +73,15 @@ public class CassandraQueryMethod extends QueryMethod { this.mappingContext = mappingContext; } + /** + * Validates that this query is not a page or slice query. + */ + @SuppressWarnings("unused") public void verify(Method method, RepositoryMetadata metadata) { // TODO: support Page & Slice queries if (isSliceQuery() || isPageQuery()) { - throw new InvalidDataAccessApiUsageException("Slice and Page queries are not supported."); + throw new InvalidDataAccessApiUsageException("Slice and Page queries are not supported"); } } @@ -92,6 +101,7 @@ public class CassandraQueryMethod extends QueryMethod { query = AnnotatedElementUtils.findMergedAnnotation(method, Query.class); queryCached = true; } + return query; } @@ -99,7 +109,7 @@ public class CassandraQueryMethod extends QueryMethod { * Returns whether the method has an annotated query. */ public boolean hasAnnotatedQuery() { - return getAnnotatedQuery() != null; + return (getAnnotatedQuery() != null); } /** @@ -110,7 +120,7 @@ public class CassandraQueryMethod extends QueryMethod { if (!queryCached) { queryString = (String) AnnotationUtils.getValue(getQueryAnnotation()); - queryString = StringUtils.hasText(queryString) ? queryString : null; + queryString = (StringUtils.hasText(queryString) ? queryString : null); } return queryString; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessor.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessor.java index ef59804f5..17c0968b6 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessor.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessor.java @@ -118,6 +118,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { } DataType parameterType = getDataType(index); + if (parameterType == null) { parameterType = cassandraConverter.getMappingContext().getDataType(getParameterType(index)); } @@ -174,5 +175,4 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { delegate.remove(); } } - } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQuery.java index 68d1a6adb..7bfa113fb 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQuery.java @@ -36,7 +36,8 @@ import com.datastax.driver.core.LocalDate; */ public class StringBasedCassandraQuery extends AbstractCassandraQuery { - @SuppressWarnings("unchecked") private static final Set> STRING_LIKE_PARAMETER_TYPES = new HashSet>( + @SuppressWarnings("unchecked") + private static final Set> STRING_LIKE_PARAMETER_TYPES = new HashSet>( Arrays.asList(CharSequence.class, char.class, Character.class, char[].class)); private static final Pattern PLACEHOLDER = Pattern.compile("\\?(\\d+)"); @@ -99,14 +100,12 @@ public class StringBasedCassandraQuery extends AbstractCassandraQuery { private boolean isStringLike(Object value) { - if (value == null) { - return false; - } + if (value != null) { + for (Class type : STRING_LIKE_PARAMETER_TYPES) { - for (Class type : STRING_LIKE_PARAMETER_TYPES) { - - if (ClassUtils.isAssignableValue(type, value)) { - return true; + if (ClassUtils.isAssignableValue(type, value)) { + return true; + } } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUnitTests.java index 1933c90d1..fcc04c42b 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUnitTests.java @@ -417,6 +417,7 @@ public class MappingCassandraConverterUnitTests { public void shouldReadDateCorrectly() { LocalDate date = LocalDate.fromDaysSinceEpoch(1234); + when(rowMock.getDate(0)).thenReturn(date); LocalDate result = mappingCassandraConverter.readRow(LocalDate.class, rowMock); @@ -468,10 +469,11 @@ public class MappingCassandraConverterUnitTests { typeWithLocalDate.localDate = now; Insert insert = QueryBuilder.insertInto("table"); + mappingCassandraConverter.write(typeWithLocalDate, insert); - assertThat(getValues(insert), - contains((Object) LocalDate.fromYearMonthDay(now.getYear(), now.getMonthValue(), now.getDayOfMonth()))); + assertThat(getValues(insert).contains(LocalDate.fromYearMonthDay(now.getYear(), now.getMonthValue(), now.getDayOfMonth())), + is(true)); } /** @@ -486,10 +488,11 @@ public class MappingCassandraConverterUnitTests { typeWithLocalDate.localDate = now; Update update = QueryBuilder.update("table"); + mappingCassandraConverter.write(typeWithLocalDate, update); - assertThat(getAssignmentValues(update), - contains((Object) LocalDate.fromYearMonthDay(now.getYear(), now.getMonthValue(), now.getDayOfMonth()))); + assertThat(getAssignmentValues(update).contains(LocalDate.fromYearMonthDay(now.getYear(), now.getMonthValue(), now.getDayOfMonth())), + is(true)); } /** @@ -499,19 +502,18 @@ public class MappingCassandraConverterUnitTests { public void shouldCreateInsertWithLocalDateListUsingCassandraDate() { java.time.LocalDate now = java.time.LocalDate.now(); + java.time.LocalDate localDate = java.time.LocalDate.of(2010, 7, 4); TypeWithLocalDate typeWithLocalDate = new TypeWithLocalDate(); - java.time.LocalDate localDate = java.time.LocalDate.of(2010, 7, 4); typeWithLocalDate.list = Arrays.asList(now, localDate); Insert insert = QueryBuilder.insertInto("table"); + mappingCassandraConverter.write(typeWithLocalDate, insert); - List values = getValues(insert); - - assertThat(values.get(0), is(instanceOf(List.class))); - List dates = (List) values.get(0); + List dates = getListValue(insert); + assertThat(dates, is(notNullValue(List.class))); assertThat(dates, hasItem(LocalDate.fromYearMonthDay(now.getYear(), now.getMonthValue(), now.getDayOfMonth()))); assertThat(dates, hasItem(LocalDate.fromYearMonthDay(2010, 7, 4))); } @@ -523,19 +525,18 @@ public class MappingCassandraConverterUnitTests { public void shouldCreateInsertWithLocalDateSetUsingCassandraDate() { java.time.LocalDate now = java.time.LocalDate.now(); + java.time.LocalDate localDate = java.time.LocalDate.of(2010, 7, 4); TypeWithLocalDate typeWithLocalDate = new TypeWithLocalDate(); - java.time.LocalDate localDate = java.time.LocalDate.of(2010, 7, 4); typeWithLocalDate.set = new HashSet(Arrays.asList(now, localDate)); Insert insert = QueryBuilder.insertInto("table"); + mappingCassandraConverter.write(typeWithLocalDate, insert); - List values = getValues(insert); - - assertThat(values.get(0), is(instanceOf(Set.class))); - Set dates = (Set) values.get(0); + Set dates = getSetValue(insert); + assertThat(dates, is(notNullValue(Set.class))); assertThat(dates, hasItem(LocalDate.fromYearMonthDay(now.getYear(), now.getMonthValue(), now.getDayOfMonth()))); assertThat(dates, hasItem(LocalDate.fromYearMonthDay(2010, 7, 4))); } @@ -571,7 +572,7 @@ public class MappingCassandraConverterUnitTests { mappingCassandraConverter.write(typeWithLocalDate, insert); - assertThat(getValues(insert), contains((Object) LocalDate.fromYearMonthDay(2010, 7, 4))); + assertThat(getValues(insert).contains(LocalDate.fromYearMonthDay(2010, 7, 4)), is(true)); } /** @@ -584,6 +585,7 @@ public class MappingCassandraConverterUnitTests { typeWithLocalDate.localDate = java.time.LocalDate.of(2010, 7, 4); Update update = QueryBuilder.update("table"); + mappingCassandraConverter.write(typeWithLocalDate, update); assertThat(getAssignmentValues(update), contains((Object) LocalDate.fromYearMonthDay(2010, 7, 4))); @@ -650,8 +652,8 @@ public class MappingCassandraConverterUnitTests { Row rowMock = RowMockUtil.newRowMock(column("id", "my-id", DataType.ascii()), column("localDate", LocalDate.fromYearMonthDay(2010, 7, 4), DataType.date())); - TypeWithJodaLocalDateMappedToDate result = mappingCassandraConverter - .readRow(TypeWithJodaLocalDateMappedToDate.class, rowMock); + TypeWithJodaLocalDateMappedToDate result = + mappingCassandraConverter.readRow(TypeWithJodaLocalDateMappedToDate.class, rowMock); assertThat(result.localDate, is(notNullValue())); assertThat(result.localDate.getYear(), is(2010)); @@ -669,9 +671,10 @@ public class MappingCassandraConverterUnitTests { typeWithLocalDate.localDate = new org.joda.time.LocalDate(2010, 7, 4); Insert insert = QueryBuilder.insertInto("table"); + mappingCassandraConverter.write(typeWithLocalDate, insert); - assertThat(getValues(insert), contains((Object) LocalDate.fromYearMonthDay(2010, 7, 4))); + assertThat(getValues(insert).contains(LocalDate.fromYearMonthDay(2010, 7, 4)), is(true)); } /** @@ -684,6 +687,7 @@ public class MappingCassandraConverterUnitTests { typeWithLocalDate.localDate = new org.joda.time.LocalDate(2010, 7, 4); Update update = QueryBuilder.update("table"); + mappingCassandraConverter.write(typeWithLocalDate, update); assertThat(getAssignmentValues(update), contains((Object) LocalDate.fromYearMonthDay(2010, 7, 4))); @@ -698,8 +702,8 @@ public class MappingCassandraConverterUnitTests { Row rowMock = RowMockUtil.newRowMock(column("id", "my-id", DataType.ascii()), column("localDate", LocalDate.fromYearMonthDay(2010, 7, 4), DataType.date())); - TypeWithThreeTenBpLocalDateMappedToDate result = mappingCassandraConverter - .readRow(TypeWithThreeTenBpLocalDateMappedToDate.class, rowMock); + TypeWithThreeTenBpLocalDateMappedToDate result = + mappingCassandraConverter.readRow(TypeWithThreeTenBpLocalDateMappedToDate.class, rowMock); assertThat(result.localDate, is(notNullValue())); assertThat(result.localDate.getYear(), is(2010)); @@ -717,9 +721,10 @@ public class MappingCassandraConverterUnitTests { typeWithLocalDate.localDate = org.threeten.bp.LocalDate.of(2010, 7, 4); Insert insert = QueryBuilder.insertInto("table"); + mappingCassandraConverter.write(typeWithLocalDate, insert); - assertThat(getValues(insert), contains((Object) LocalDate.fromYearMonthDay(2010, 7, 4))); + assertThat(getValues(insert).contains(LocalDate.fromYearMonthDay(2010, 7, 4)), is(true)); } /** @@ -737,6 +742,31 @@ public class MappingCassandraConverterUnitTests { assertThat(getAssignmentValues(update), contains((Object) LocalDate.fromYearMonthDay(2010, 7, 4))); } + @SuppressWarnings("unchecked") + private List getListValue(Insert statement) { + List values = getValues(statement); + + for (Object value : values) { + if (value instanceof List) { + return (List) value; + } + } + + return null; + } + + @SuppressWarnings("unchecked") + private Set getSetValue(Insert statement) { + List values = getValues(statement); + + for (Object value : values) { + if (value instanceof Set) { + return (Set) value; + } + } + + return null; + } @SuppressWarnings("unchecked") private List getValues(Insert statement) { @@ -875,7 +905,7 @@ public class MappingCassandraConverterUnitTests { } } - public static enum Condition { + public enum Condition { MINT, USED; } 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 c0b0a87f8..d84490781 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 @@ -29,10 +29,8 @@ import org.springframework.data.cassandra.mapping.CassandraType; import org.springframework.data.cassandra.mapping.PrimaryKey; import org.springframework.data.cassandra.mapping.Table; import org.springframework.data.cassandra.test.integration.mapping.types.CassandraTypeMappingIntegrationTest.Condition; -import org.threeten.bp.LocalDateTime; import com.datastax.driver.core.DataType.Name; -import com.datastax.driver.core.LocalDate; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/MappingContextUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/MappingContextUnitTests.java index f17d1e176..581c61b59 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/MappingContextUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/MappingContextUnitTests.java @@ -39,11 +39,11 @@ import org.springframework.data.util.ClassTypeInformation; */ public class MappingContextUnitTests { - BasicCassandraMappingContext ctx = new BasicCassandraMappingContext(); + BasicCassandraMappingContext mappingContext = new BasicCassandraMappingContext(); @Test(expected = MappingException.class) public void testGetPersistentEntityOfTransientType() { - ctx.getPersistentEntity(Transient.class); + mappingContext.getPersistentEntity(Transient.class); } private static class Transient {} @@ -51,11 +51,11 @@ public class MappingContextUnitTests { @Test public void testGetExistingPersistentEntityHappyPath() { - ctx.getPersistentEntity(X.class); + mappingContext.getPersistentEntity(X.class); - assertTrue(ctx.contains(X.class)); - assertNotNull(ctx.getExistingPersistentEntity(X.class)); - assertFalse(ctx.contains(Y.class)); + assertTrue(mappingContext.contains(X.class)); + assertNotNull(mappingContext.getExistingPersistentEntity(X.class)); + assertFalse(mappingContext.contains(Y.class)); } @Table @@ -74,12 +74,14 @@ public class MappingContextUnitTests { @Test public void primaryKeyOnPropertyShouldWork() { - CassandraPersistentEntity persistentEntity = ctx.getPersistentEntity(PrimaryKeyOnProperty.class); + CassandraPersistentEntity persistentEntity = mappingContext.getPersistentEntity(PrimaryKeyOnProperty.class); CassandraPersistentProperty idProperty = persistentEntity.getIdProperty(); + assertThat(idProperty.getColumnName().toCql(), is(equalTo("foo"))); List columnNames = idProperty.getColumnNames(); + assertThat(columnNames, hasSize(1)); assertThat(columnNames.get(0).toCql(), is(equalTo("foo"))); } @@ -105,17 +107,19 @@ public class MappingContextUnitTests { @Test public void primaryKeyColumnsOnPropertyShouldWork() { - CassandraPersistentEntity persistentEntity = ctx.getPersistentEntity(PrimaryKeyColumnsOnProperty.class); + CassandraPersistentEntity persistentEntity = mappingContext.getPersistentEntity(PrimaryKeyColumnsOnProperty.class); assertThat(persistentEntity.isCompositePrimaryKey(), is(false)); CassandraPersistentProperty firstname = persistentEntity.getPersistentProperty("firstname"); + assertThat(firstname.isCompositePrimaryKey(), is(false)); assertThat(firstname.isPrimaryKeyColumn(), is(true)); assertThat(firstname.isPartitionKeyColumn(), is(true)); assertThat(firstname.getColumnName().toCql(), is(equalTo("firstname"))); CassandraPersistentProperty lastname = persistentEntity.getPersistentProperty("lastname"); + assertThat(lastname.isPrimaryKeyColumn(), is(true)); assertThat(lastname.isClusterKeyColumn(), is(true)); assertThat(lastname.getColumnName().toCql(), is(equalTo("mylastname"))); @@ -152,10 +156,11 @@ public class MappingContextUnitTests { @Test public void primaryKeyClassWithprimaryKeyColumnsOnPropertyShouldWork() { - CassandraPersistentEntity persistentEntity = ctx - .getPersistentEntity(PrimaryKeyOnPropertyWithPrimaryKeyClass.class); - CassandraPersistentEntity primaryKeyClass = ctx - .getPersistentEntity(CompositePrimaryKeyClassWithProperties.class); + CassandraPersistentEntity persistentEntity = + mappingContext.getPersistentEntity(PrimaryKeyOnPropertyWithPrimaryKeyClass.class); + + CassandraPersistentEntity primaryKeyClass = + mappingContext.getPersistentEntity(CompositePrimaryKeyClassWithProperties.class); assertThat(persistentEntity.isCompositePrimaryKey(), is(false)); assertThat(persistentEntity.getPersistentProperty("key").isCompositePrimaryKey(), is(true)); @@ -164,12 +169,14 @@ public class MappingContextUnitTests { assertThat(primaryKeyClass.getCompositePrimaryKeyProperties(), hasSize(2)); CassandraPersistentProperty firstname = primaryKeyClass.getPersistentProperty("firstname"); + assertThat(firstname.isPrimaryKeyColumn(), is(true)); assertThat(firstname.isPartitionKeyColumn(), is(true)); assertThat(firstname.isClusterKeyColumn(), is(false)); assertThat(firstname.getColumnName().toCql(), is(equalTo("firstname"))); CassandraPersistentProperty lastname = primaryKeyClass.getPersistentProperty("lastname"); + assertThat(lastname.isPrimaryKeyColumn(), is(true)); assertThat(lastname.isPartitionKeyColumn(), is(false)); assertThat(lastname.isClusterKeyColumn(), is(true)); @@ -222,8 +229,8 @@ public class MappingContextUnitTests { @Test public void shouldCreatePersistentEntityIfNoConversionRegistered() { - ctx.setCustomConversions(new CustomConversions(Collections.EMPTY_LIST)); - assertThat(ctx.shouldCreatePersistentEntityFor(ClassTypeInformation.from(Human.class)), is(true)); + mappingContext.setCustomConversions(new CustomConversions(Collections.EMPTY_LIST)); + assertThat(mappingContext.shouldCreatePersistentEntityFor(ClassTypeInformation.from(Human.class)), is(true)); } /** @@ -233,13 +240,12 @@ public class MappingContextUnitTests { public void shouldNotCreateEntitiesForCustomConvertedTypes() { List converters = Arrays.asList(new HumanToStringConverter()); - ctx.setCustomConversions(new CustomConversions(converters)); + mappingContext.setCustomConversions(new CustomConversions(converters)); - assertThat(ctx.shouldCreatePersistentEntityFor(ClassTypeInformation.from(Human.class)), is(false)); + assertThat(mappingContext.shouldCreatePersistentEntityFor(ClassTypeInformation.from(Human.class)), is(false)); } private static class Human { - } private static class HumanToStringConverter implements Converter { 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 82afd4c4c..2ed2314fd 100644 --- 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 @@ -15,8 +15,6 @@ */ package org.springframework.data.cassandra.repository.isolated; -import static java.time.Instant.*; -import static java.time.ZoneId.*; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; @@ -25,7 +23,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; -import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Optional; @@ -119,7 +117,8 @@ public class RepositoryQueryMethodParameterTypesIntegrationTests @Test public void shouldFindByAnnotatedDateParameter() { - CustomConversions customConversions = new CustomConversions(Arrays.asList(new DateToLocalDateConverter())); + CustomConversions customConversions = new CustomConversions( + Collections.singletonList(new DateToLocalDateConverter())); mappingContext.setCustomConversions(customConversions); converter.setCustomConversions(customConversions); @@ -223,10 +222,10 @@ public class RepositoryQueryMethodParameterTypesIntegrationTests @Override public com.datastax.driver.core.LocalDate convert(Date source) { - LocalDate localDate = LocalDateTime.ofInstant(ofEpochMilli(source.getTime()), systemDefault()).toLocalDate(); + LocalDate localDate = LocalDateTime.ofInstant(source.toInstant(), ZoneOffset.UTC.normalized()).toLocalDate(); + return com.datastax.driver.core.LocalDate.fromYearMonthDay(localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()); } } - } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/config/SchemaActionIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/config/SchemaActionIntegrationTests.java index d94aaf85b..d00784d38 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/config/SchemaActionIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/config/SchemaActionIntegrationTests.java @@ -56,15 +56,18 @@ public class SchemaActionIntegrationTests extends AbstractEmbeddedCassandraInteg protected static final String KEYSPACE_NAME = SchemaActionIntegrationTests.class.getSimpleName().toLowerCase(); - protected static final String PERSON_TABLE_DEFINITION_CQL = String - .format("CREATE TABLE %s.person (id int, firstName text, lastName text, PRIMARY KEY(id));", KEYSPACE_NAME); + protected static final String PERSON_TABLE_DEFINITION_CQL = String.format( + "CREATE TABLE %s.person (id int, firstName text, lastName text, PRIMARY KEY(id));", KEYSPACE_NAME); - @Rule public ExpectedException exception = ExpectedException.none(); + @Rule + public ExpectedException exception = ExpectedException.none(); - @Rule public KeyspaceRule KEYSPACE_RULE = new KeyspaceRule(cassandraEnvironment, KEYSPACE_NAME); + @Rule + public KeyspaceRule KEYSPACE_RULE = new KeyspaceRule(cassandraEnvironment, KEYSPACE_NAME); protected ConfigurableApplicationContext newApplicationContext(Class... annotatedClasses) { - AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(annotatedClasses); + AnnotationConfigApplicationContext applicationContext = + new AnnotationConfigApplicationContext(annotatedClasses); applicationContext.registerShutdownHook();