From b399c0a0694d0581008592cd7d36d86e460adb88 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 25 May 2023 14:08:06 +0200 Subject: [PATCH] Revise simple query and update value conversion. We now defer simple value conversion in the converter to ensure we're converting all complex values first. We also apply conversion if the value isn't assignable to the requested target type. We removed double-conversion from part-tree queries to avoid duplicate conversion. Closes #1384 --- .../convert/DefaultColumnTypeResolver.java | 10 +++ .../convert/MappingCassandraConverter.java | 62 +++++++++---------- .../query/AbstractCassandraQuery.java | 29 ++++----- .../query/AbstractReactiveCassandraQuery.java | 10 +-- .../query/CassandraQueryCreator.java | 29 ++++----- .../query/ConvertingParameterAccessor.java | 37 ++--------- .../ReactiveStringBasedCassandraQuery.java | 7 ++- .../query/StringBasedCassandraQuery.java | 10 +-- .../core/convert/QueryMapperUnitTests.java | 35 ++++++++--- .../query/CassandraQueryCreatorUnitTests.java | 20 +++--- .../ConvertingParameterAccessorUnitTests.java | 25 +------- .../StringBasedCassandraQueryUnitTests.java | 4 +- 12 files changed, 120 insertions(+), 158 deletions(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/DefaultColumnTypeResolver.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/DefaultColumnTypeResolver.java index e703d1c90..ada8be125 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/DefaultColumnTypeResolver.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/DefaultColumnTypeResolver.java @@ -500,6 +500,16 @@ class DefaultColumnTypeResolver implements ColumnTypeResolver { public DataType getDataType() { throw new MappingException(String.format("Cannot resolve DataType for %s", getType().getName())); } + + @Override + public boolean isTupleType() { + return false; + } + + @Override + public boolean isUserDefinedType() { + return false; + } } } 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 ed24dd730..5d2998da6 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 @@ -36,30 +36,15 @@ import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntity; -import org.springframework.data.cassandra.core.mapping.BasicMapId; -import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; -import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity; -import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; -import org.springframework.data.cassandra.core.mapping.Column; -import org.springframework.data.cassandra.core.mapping.Element; -import org.springframework.data.cassandra.core.mapping.Embedded; +import org.springframework.data.cassandra.core.mapping.*; import org.springframework.data.cassandra.core.mapping.Embedded.OnEmpty; -import org.springframework.data.cassandra.core.mapping.EmbeddedEntityOperations; -import org.springframework.data.cassandra.core.mapping.MapId; -import org.springframework.data.cassandra.core.mapping.MapIdentifiable; -import org.springframework.data.cassandra.core.mapping.PersistentPropertyTranslator; -import org.springframework.data.cassandra.core.mapping.UserTypeResolver; import org.springframework.data.convert.CustomConversions; -import org.springframework.data.mapping.AccessOptions; import org.springframework.data.mapping.InstanceCreatorMetadata; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; -import org.springframework.data.mapping.PersistentPropertyPath; -import org.springframework.data.mapping.PersistentPropertyPathAccessor; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator; @@ -347,8 +332,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter CassandraValueProvider valueProviderToUse = new TranslatingCassandraValueProvider(propertyTranslator, valueProvider); - InstanceCreatorMetadata persistenceCreator = mappedEntity - .getInstanceCreatorMetadata(); + InstanceCreatorMetadata persistenceCreator = mappedEntity.getInstanceCreatorMetadata(); ParameterValueProvider provider; if (persistenceCreator != null && persistenceCreator.hasParameters()) { @@ -922,10 +906,6 @@ public class MappingCassandraConverter extends AbstractCassandraConverter return getConversionService().convert(value, resolvedTargetType); } - if (getCustomConversions().isSimpleType(value.getClass())) { - return getPotentiallyConvertedSimpleValue(value, requestedTargetType); - } - if (value instanceof Collection) { return writeCollectionInternal((Collection) value, columnType); } @@ -938,29 +918,41 @@ public class MappingCassandraConverter extends AbstractCassandraConverter TypeInformation actualType = type.getRequiredActualType(); BasicCassandraPersistentEntity entity = getMappingContext().getPersistentEntity(actualType.getType()); - if (entity != null && columnType instanceof CassandraColumnType) { + if (columnType instanceof CassandraColumnType cassandraType) { - CassandraColumnType cassandraType = (CassandraColumnType) columnType; + if (cassandraType.isTupleType()) { - if (entity.isTupleType() && cassandraType.isTupleType()) { + if (entity != null && entity.isTupleType()) { - TupleValue tupleValue = ((TupleType) cassandraType.getDataType()).newValue(); + TupleValue tupleValue = ((TupleType) cassandraType.getDataType()).newValue(); + write(value, tupleValue, entity); + return tupleValue; + } - write(value, tupleValue, entity); - - return tupleValue; + if (value instanceof TupleValue) { + return value; + } } - if (entity.isUserDefinedType() && cassandraType.isUserDefinedType()) { + if (cassandraType.isUserDefinedType()) { - UdtValue udtValue = ((UserDefinedType) cassandraType.getDataType()).newValue(); + if (entity != null && entity.isUserDefinedType()) { - write(value, udtValue, entity); + UdtValue udtValue = ((UserDefinedType) cassandraType.getDataType()).newValue(); + write(value, udtValue, entity); + return udtValue; + } - return udtValue; + if (value instanceof UdtValue) { + return value; + } } } + if (getCustomConversions().isSimpleType(value.getClass())) { + return getPotentiallyConvertedSimpleValue(value, requestedTargetType); + } + return value; } @@ -1017,6 +1009,10 @@ public class MappingCassandraConverter extends AbstractCassandraConverter return ((Enum) value).name(); } + if (requestedTargetType != null && !ClassUtils.isAssignableValue(requestedTargetType, value)) { + return getConversionService().convert(value, requestedTargetType); + } + return value; } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java index 5268448a3..4d80f983c 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java @@ -47,18 +47,6 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup private final CassandraOperations operations; - - private static CassandraConverter toConverter(CassandraOperations operations) { - - Assert.notNull(operations, "CassandraOperations must not be null"); - - return operations.getConverter(); - } - - private static CassandraMappingContext toMappingContext(CassandraOperations operations) { - return toConverter(operations).getMappingContext(); - } - /** * Create a new {@link AbstractCassandraQuery} from the given {@link CassandraQueryMethod} and * {@link CassandraOperations}. @@ -87,11 +75,9 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup @Override public Object execute(Object[] parameters) { - CassandraParameterAccessor parameterAccessor = new ConvertingParameterAccessor(toConverter(getOperations()), - new CassandraParametersParameterAccessor(getQueryMethod(), parameters)); - + CassandraParameterAccessor parameterAccessor = new CassandraParametersParameterAccessor(getQueryMethod(), + parameters); ResultProcessor resultProcessor = getQueryMethod().getResultProcessor().withDynamicProjection(parameterAccessor); - Statement statement = createQuery(parameterAccessor); CassandraQueryExecution queryExecution = getExecution(parameterAccessor, @@ -183,4 +169,15 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup * @since 2.2 */ protected abstract boolean isModifyingQuery(); + + private static CassandraConverter toConverter(CassandraOperations operations) { + + Assert.notNull(operations, "CassandraOperations must not be null"); + + return operations.getConverter(); + } + + private static CassandraMappingContext toMappingContext(CassandraOperations operations) { + return toConverter(operations).getMappingContext(); + } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractReactiveCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractReactiveCassandraQuery.java index c7d53efe2..2ff8df085 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractReactiveCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractReactiveCassandraQuery.java @@ -81,14 +81,8 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository private Publisher executeLater(ReactiveCassandraParameterAccessor parameterAccessor) { - CassandraParameterAccessor convertingParameterAccessor = new ConvertingParameterAccessor( - getRequiredConverter(getReactiveCassandraOperations()), parameterAccessor); - - Mono statement = createQuery(convertingParameterAccessor); - - ResultProcessor resultProcessor = getQueryMethod().getResultProcessor() - .withDynamicProjection(convertingParameterAccessor); - + Mono statement = createQuery(parameterAccessor); + ResultProcessor resultProcessor = getQueryMethod().getResultProcessor().withDynamicProjection(parameterAccessor); ReactiveCassandraQueryExecution queryExecution = getExecution(parameterAccessor, new ResultProcessingConverter( resultProcessor, getRequiredMappingContext(getReactiveCassandraOperations()), getEntityInstantiators())); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreator.java index 89bdc177e..f3b47d715 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreator.java @@ -30,7 +30,6 @@ import org.springframework.data.cassandra.core.query.Criteria; import org.springframework.data.cassandra.core.query.CriteriaDefinition; import org.springframework.data.cassandra.core.query.Filter; import org.springframework.data.cassandra.core.query.Query; -import org.springframework.data.cassandra.repository.query.ConvertingParameterAccessor.PotentiallyConvertingIterator; import org.springframework.data.domain.Range; import org.springframework.data.domain.Sort; import org.springframework.data.mapping.PersistentPropertyPath; @@ -104,8 +103,7 @@ class CassandraQueryCreator extends AbstractQueryCreator { Assert.state(property != null && path.toDotPath() != null, "Leaf property must not be null"); - Object filterOrCriteria = from(part, property, Criteria.where(path.toDotPath()), - (PotentiallyConvertingIterator) iterator); + Object filterOrCriteria = from(part, property, Criteria.where(path.toDotPath()), iterator); if (filterOrCriteria instanceof CriteriaDefinition) { return Filter.from((CriteriaDefinition) filterOrCriteria); @@ -151,38 +149,37 @@ class CassandraQueryCreator extends AbstractQueryCreator { /** * Returns a {@link Filter} or {@link CriteriaDefinition} object representing the criterion for a {@link Part}. */ - private Object from(Part part, CassandraPersistentProperty property, Criteria where, - PotentiallyConvertingIterator parameters) { + private Object from(Part part, CassandraPersistentProperty property, Criteria where, Iterator parameters) { Type type = part.getType(); switch (type) { case AFTER: case GREATER_THAN: - return where.gt(parameters.nextConverted(property)); + return where.gt(parameters.next()); case GREATER_THAN_EQUAL: - return where.gte(parameters.nextConverted(property)); + return where.gte(parameters.next()); case BEFORE: case LESS_THAN: - return where.lt(parameters.nextConverted(property)); + return where.lt(parameters.next()); case LESS_THAN_EQUAL: - return where.lte(parameters.nextConverted(property)); + return where.lte(parameters.next()); case BETWEEN: return computeBetweenPart(where, parameters); case IN: - return where.in(nextAsArray(property, parameters)); + return where.in(nextAsArray(parameters)); case LIKE: case STARTING_WITH: case ENDING_WITH: - return where.like(like(type, parameters.nextConverted(property))); + return where.like(like(type, parameters.next())); case CONTAINING: - return containing(where, property, parameters.nextConverted(property)); + return containing(where, property, parameters.next()); case TRUE: return where.is(true); case FALSE: return where.is(false); case SIMPLE_PROPERTY: - return where.is(parameters.nextConverted(property)); + return where.is(parameters.next()); default: throw new InvalidDataAccessApiUsageException( String.format("Unsupported keyword [%s] in part [%s]", type, part)); @@ -193,7 +190,7 @@ class CassandraQueryCreator extends AbstractQueryCreator { * Compute a {@link Type#BETWEEN} {@link Part}. *

* In case the first {@literal value} is actually a {@link Range} the lower and upper bounds of the {@link Range} are - * used according to their {@link Range.Bound#isInclusive() inclusion} definition. Otherwise the {@literal value} is + * used according to their {@link Range.Bound#isInclusive() inclusion} definition. Otherwise, the {@literal value} is * used for greater than and {@link Iterator#next() parameters.next()} as less than criterions. * * @param where must not be {@literal null}. @@ -260,9 +257,9 @@ class CassandraQueryCreator extends AbstractQueryCreator { throw new IllegalArgumentException(String.format("Part Type [%s] not supported with like queries", type)); } - private Object[] nextAsArray(CassandraPersistentProperty property, PotentiallyConvertingIterator iterator) { + private Object[] nextAsArray(Iterator iterator) { - Object next = iterator.nextConverted(property); + Object next = iterator.next(); if (next instanceof Collection) { return ((Collection) next).toArray(); 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 cf405689e..b5fee87a6 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 @@ -15,12 +15,10 @@ */ package org.springframework.data.cassandra.repository.query; -import java.util.Collection; import java.util.Iterator; import org.springframework.data.cassandra.core.convert.CassandraConverter; import org.springframework.data.cassandra.core.cql.QueryOptions; -import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; import org.springframework.data.cassandra.core.mapping.CassandraType; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Range; @@ -74,7 +72,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { @Override public Object getBindableValue(int index) { - return potentiallyConvert(index, this.delegate.getBindableValue(index), null); + return potentiallyConvert(index, this.delegate.getBindableValue(index)); } @Override @@ -114,7 +112,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { @SuppressWarnings("unchecked") @Nullable - Object potentiallyConvert(int index, @Nullable Object bindableValue, @Nullable CassandraPersistentProperty property) { + Object potentiallyConvert(int index, @Nullable Object bindableValue) { if (bindableValue == null) { return null; @@ -130,11 +128,6 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { this.converter.convertToColumnType(bindableValue, converter.getColumnTypeResolver().resolve(cassandraType)); } - if (property != null && ((property.isCollectionLike() && bindableValue instanceof Collection) - || (!property.isCollectionLike() && !(bindableValue instanceof Collection)))) { - return this.converter.convertToColumnType(bindableValue, converter.getColumnTypeResolver().resolve(property)); - } - return this.converter.convertToColumnType(bindableValue, converter.getColumnTypeResolver().resolve(bindableValue)); } @@ -143,7 +136,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { * * @author Mark Paluch */ - private class ConvertingIterator implements PotentiallyConvertingIterator { + private class ConvertingIterator implements Iterator { private final Iterator delegate; @@ -164,34 +157,12 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { @Nullable public Object next() { - return potentiallyConvert(this.index++, this.delegate.next(), null); + return potentiallyConvert(this.index++, this.delegate.next()); } public void remove() { this.delegate.remove(); } - @Nullable - @Override - public Object nextConverted(CassandraPersistentProperty property) { - return potentiallyConvert(this.index++, this.delegate.next(), property); - } - } - - /** - * Custom {@link Iterator} that adds a method to access elements in a converted manner. - * - * @author Mark Paluch - */ - interface PotentiallyConvertingIterator extends Iterator { - - /** - * Returns the next element and pass in type information for potential conversion. - * - * @return the converted object, may be {@literal null}. - */ - @Nullable - Object nextConverted(CassandraPersistentProperty property); - } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQuery.java index 7d17c99f6..18079eb4a 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQuery.java @@ -124,11 +124,12 @@ public class ReactiveStringBasedCassandraQuery extends AbstractReactiveCassandra public Mono createQuery(CassandraParameterAccessor parameterAccessor) { StringBasedQuery query = getStringBasedQuery(); - + ConvertingParameterAccessor parameterAccessorToUse = new ConvertingParameterAccessor( + getReactiveCassandraOperations().getConverter(), parameterAccessor); Mono spelEvaluator = getSpelEvaluatorFor(query.getExpressionDependencies(), - parameterAccessor); + parameterAccessorToUse); - return spelEvaluator.map(it -> getQueryStatementCreator().select(query, parameterAccessor, it)); + return spelEvaluator.map(it -> getQueryStatementCreator().select(query, parameterAccessorToUse, it)); } @Override 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 6f6b15b09..e9daca9bb 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 @@ -88,8 +88,7 @@ public class StringBasedCassandraQuery extends AbstractCassandraQuery { this.expressionParser = expressionParser; this.evaluationContextProvider = evaluationContextProvider; - this.stringBasedQuery = new StringBasedQuery(query, - method.getParameters(), expressionParser); + this.stringBasedQuery = new StringBasedQuery(query, method.getParameters(), expressionParser); if (method.hasAnnotatedQuery()) { @@ -115,11 +114,12 @@ public class StringBasedCassandraQuery extends AbstractCassandraQuery { public SimpleStatement createQuery(CassandraParameterAccessor parameterAccessor) { StringBasedQuery query = getStringBasedQuery(); - + ConvertingParameterAccessor parameterAccessorToUse = new ConvertingParameterAccessor(getOperations().getConverter(), + parameterAccessor); EvaluationContext evaluationContext = evaluationContextProvider.getEvaluationContext( - getQueryMethod().getParameters(), parameterAccessor.getValues(), query.getExpressionDependencies()); + getQueryMethod().getParameters(), parameterAccessorToUse.getValues(), query.getExpressionDependencies()); - return getQueryStatementCreator().select(query, parameterAccessor, + return getQueryStatementCreator().select(query, parameterAccessorToUse, new DefaultSpELExpressionEvaluator(expressionParser, evaluationContext)); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/QueryMapperUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/QueryMapperUnitTests.java index ef496df17..b8f8ad062 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/QueryMapperUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/convert/QueryMapperUnitTests.java @@ -44,6 +44,7 @@ import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity import org.springframework.data.cassandra.core.mapping.Column; import org.springframework.data.cassandra.core.mapping.Element; import org.springframework.data.cassandra.core.mapping.Embedded; +import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn; import org.springframework.data.cassandra.core.mapping.Tuple; import org.springframework.data.cassandra.core.mapping.UserDefinedType; import org.springframework.data.cassandra.core.mapping.UserTypeResolver; @@ -378,14 +379,6 @@ public class QueryMapperUnitTests { Filter mappedFilter = this.queryMapper. getMappedObject(filter, this.personPersistentEntity); - /* - mappedFilter.get().findFirst() - .map(CriteriaDefinition::getPredicate) - .map(CriteriaDefinition.Predicate::getValue) - .map(Object::getClass) - .ifPresent(System.out::println); - */ - assertThat(mappedFilter).contains(Criteria.where("localtime").gt(time)); } @@ -418,6 +411,18 @@ public class QueryMapperUnitTests { assertThat(mappedObject.iterator().next().getColumnName()).isEqualTo(ColumnName.from("prefixfirstname")); } + @Test // GH-1383 + void shouldConvertPrimaryKeyValues() { + + Filter filter = Filter.from(Criteria.where("id.foo").is(42)); + + Filter mappedObject = this.queryMapper.getMappedObject(filter, + this.mappingContext.getRequiredPersistentEntity(WithPrimaryKeyClass.class)); + + assertThat(mappedObject.iterator().next().getColumnName()).isEqualTo(ColumnName.from("foo")); + assertThat(mappedObject.iterator().next().getPredicate().getValue()).isEqualTo(42L); + } + @SuppressWarnings("unused") static class Person { @@ -440,6 +445,20 @@ public class QueryMapperUnitTests { } + static class WithPrimaryKeyClass { + + @Id MyPrimaryKeyClass id; + + } + + static class MyPrimaryKeyClass { + + @PrimaryKeyColumn long foo; + + @PrimaryKeyColumn long bar; + + } + @Tuple @AllArgsConstructor static class MappedTuple { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreatorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreatorUnitTests.java index f3b36c8db..0cf0672e4 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreatorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreatorUnitTests.java @@ -140,18 +140,18 @@ class CassandraQueryCreatorUnitTests { @Test // DATACASS-627 void createsBetweenQueryCorrectly() { - String query = createQuery("findByFirstnameBetween", Person.class, 1, 2); + String query = createQuery("findByNumberOfChildrenBetween", Person.class, 1, 2); - assertThat(query).isEqualTo("SELECT * FROM person WHERE firstname>1 AND firstname<2"); + assertThat(query).isEqualTo("SELECT * FROM person WHERE numberofchildren>1 AND numberofchildren<2"); } @Test // DATACASS-627 void createsBetweenQueryWithRangeCorrectly() { - String query = createQuery("findByFirstnameBetween", Person.class, + String query = createQuery("findByNumberOfChildrenBetween", Person.class, Range.from(Range.Bound.inclusive(1)).to(Range.Bound.exclusive(2))); - assertThat(query).isEqualTo("SELECT * FROM person WHERE firstname>=1 AND firstname<2"); + assertThat(query).isEqualTo("SELECT * FROM person WHERE numberofchildren>=1 AND numberofchildren<2"); } @Test // DATACASS-7 @@ -239,25 +239,25 @@ class CassandraQueryCreatorUnitTests { @Test // DATACASS-7 void createsIsTrueQueryCorrectly() { - String query = createQuery("findByFirstnameIsTrue", Person.class, "Walter"); + String query = createQuery("findByCoolIsTrue", Person.class, "Walter"); - assertThat(query).isEqualTo("SELECT * FROM person WHERE firstname=true"); + assertThat(query).isEqualTo("SELECT * FROM person WHERE cool=true"); } @Test // DATACASS-7 void createsIsFalseQueryCorrectly() { - String query = createQuery("findByFirstnameIsFalse", Person.class, "Walter"); + String query = createQuery("findByCoolIsFalse", Person.class, "Walter"); - assertThat(query).isEqualTo("SELECT * FROM person WHERE firstname=false"); + assertThat(query).isEqualTo("SELECT * FROM person WHERE cool=false"); } @Test // DATACASS-7 void createsQueryUsingQuotingCorrectly() { - String query = createQuery("findByIdAndSet", QuotedType.class, "Walter", "White"); + String query = createQuery("findByIdAndSet", QuotedType.class, "Walter", Arrays.asList("White")); - assertThat(query).isEqualTo("SELECT * FROM \"myTable\" WHERE my_id='Walter' AND \"set\"='White'"); + assertThat(query).isEqualTo("SELECT * FROM \"myTable\" WHERE my_id='Walter' AND \"set\"={'White'}"); } @Test // DATACASS-7 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 c04e4a495..13f6d60f5 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,9 +19,6 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; import java.time.LocalDate; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -30,7 +27,6 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; -import org.springframework.data.cassandra.repository.query.ConvertingParameterAccessor.PotentiallyConvertingIterator; import com.datastax.oss.driver.api.core.type.DataTypes; @@ -83,8 +79,7 @@ class ConvertingParameterAccessorUnitTests { when(mockParameterAccessor.getBindableValue(0)).thenReturn(localDate); - assertThat(convertingParameterAccessor.getBindableValue(0)) - .isEqualTo(LocalDate.of(2010, 7, 4)); + assertThat(convertingParameterAccessor.getBindableValue(0)).isEqualTo(LocalDate.of(2010, 7, 4)); } @Test // DATACASS-296, DATACASS-7 @@ -95,22 +90,4 @@ class ConvertingParameterAccessorUnitTests { assertThat(convertingParameterAccessor.getDataType(0)).isEqualTo(DataTypes.TEXT); } - @Test // DATACASS-296, DATACASS-7 - @SuppressWarnings({ "rawtypes", "unchecked" }) - void shouldConvertCollections() { - - LocalDate localDate = LocalDate.of(2010, 7, 4); - - when(mockParameterAccessor.iterator()) - .thenReturn((Iterator) Collections.singletonList(Collections.singletonList(localDate)).iterator()); - - PotentiallyConvertingIterator iterator = (PotentiallyConvertingIterator) convertingParameterAccessor.iterator(); - Object converted = iterator.nextConverted(mockProperty); - - assertThat(converted).isInstanceOf(List.class); - - List list = (List) converted; - - assertThat(list.get(0)).isInstanceOf(LocalDate.class); - } } 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 d658c4308..febbd2ee3 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 @@ -335,7 +335,7 @@ class StringBasedCassandraQueryUnitTests { } @Test // DATACASS-172 - void bindsMappedUdtPropertyCorrectly() throws Exception { + void bindsMappedUdtPropertyCorrectly() { UserDefinedType addressType = UserDefinedTypeBuilder.forName("address").withField("city", DataTypes.TEXT) .withField("country", DataTypes.TEXT).build(); @@ -353,7 +353,7 @@ class StringBasedCassandraQueryUnitTests { } @Test // DATACASS-172 - void bindsUdtValuePropertyCorrectly() throws Exception { + void bindsUdtValuePropertyCorrectly() { StringBasedCassandraQuery cassandraQuery = getQueryMethod("findByMainAddress", UdtValue.class);