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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<CassandraPersistentProperty> persistenceCreator = mappedEntity
|
||||
.getInstanceCreatorMetadata();
|
||||
InstanceCreatorMetadata<CassandraPersistentProperty> persistenceCreator = mappedEntity.getInstanceCreatorMetadata();
|
||||
|
||||
ParameterValueProvider<CassandraPersistentProperty> 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<Object>) 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,14 +81,8 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository
|
||||
|
||||
private Publisher<Object> executeLater(ReactiveCassandraParameterAccessor parameterAccessor) {
|
||||
|
||||
CassandraParameterAccessor convertingParameterAccessor = new ConvertingParameterAccessor(
|
||||
getRequiredConverter(getReactiveCassandraOperations()), parameterAccessor);
|
||||
|
||||
Mono<SimpleStatement> statement = createQuery(convertingParameterAccessor);
|
||||
|
||||
ResultProcessor resultProcessor = getQueryMethod().getResultProcessor()
|
||||
.withDynamicProjection(convertingParameterAccessor);
|
||||
|
||||
Mono<SimpleStatement> statement = createQuery(parameterAccessor);
|
||||
ResultProcessor resultProcessor = getQueryMethod().getResultProcessor().withDynamicProjection(parameterAccessor);
|
||||
ReactiveCassandraQueryExecution queryExecution = getExecution(parameterAccessor, new ResultProcessingConverter(
|
||||
resultProcessor, getRequiredMappingContext(getReactiveCassandraOperations()), getEntityInstantiators()));
|
||||
|
||||
|
||||
@@ -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<Query, Filter> {
|
||||
|
||||
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<Query, Filter> {
|
||||
/**
|
||||
* 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<Object> 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<Query, Filter> {
|
||||
* Compute a {@link Type#BETWEEN} {@link Part}.
|
||||
* <p>
|
||||
* 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<Query, Filter> {
|
||||
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<Object> iterator) {
|
||||
|
||||
Object next = iterator.nextConverted(property);
|
||||
Object next = iterator.next();
|
||||
|
||||
if (next instanceof Collection) {
|
||||
return ((Collection<?>) next).toArray();
|
||||
|
||||
@@ -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<Object> {
|
||||
|
||||
private final Iterator<Object> 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<Object> {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,11 +124,12 @@ public class ReactiveStringBasedCassandraQuery extends AbstractReactiveCassandra
|
||||
public Mono<SimpleStatement> createQuery(CassandraParameterAccessor parameterAccessor) {
|
||||
|
||||
StringBasedQuery query = getStringBasedQuery();
|
||||
|
||||
ConvertingParameterAccessor parameterAccessorToUse = new ConvertingParameterAccessor(
|
||||
getReactiveCassandraOperations().getConverter(), parameterAccessor);
|
||||
Mono<SpELExpressionEvaluator> 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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user