DATACASS-318 - Allow configuration of CodecRegistry in CassandraMappingContext.
We now allow configuration of CodecRegistry in CassandraMappingContext to reuse the configured instance instead of using the default CodecRegistry instance.
This commit is contained in:
@@ -160,6 +160,7 @@ public abstract class AbstractCassandraConfiguration extends AbstractClusterConf
|
||||
|
||||
mappingContext.setCustomConversions(customConversions);
|
||||
mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
|
||||
mappingContext.setCodecRegistry(cluster.getConfiguration().getCodecRegistry());
|
||||
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.data.mapping.model.SpELExpressionEvaluator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.CodecRegistry;
|
||||
import com.datastax.driver.core.Row;
|
||||
|
||||
/**
|
||||
@@ -38,18 +39,21 @@ public class BasicCassandraRowValueProvider implements CassandraRowValueProvider
|
||||
private final SpELExpressionEvaluator evaluator;
|
||||
|
||||
/**
|
||||
* Create a new {@link BasicCassandraRowValueProvider} with the given {@link Row} and {@link SpELExpressionEvaluator}.
|
||||
* Create a new {@link BasicCassandraRowValueProvider} with the given {@link Row}, {@link CodecRegistry} and
|
||||
* {@link SpELExpressionEvaluator}.
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @param codecRegistry must not be {@literal null}.
|
||||
* @param evaluator must not be {@literal null}.
|
||||
* @since 2.1
|
||||
*/
|
||||
public BasicCassandraRowValueProvider(Row source, SpELExpressionEvaluator evaluator) {
|
||||
public BasicCassandraRowValueProvider(Row source, CodecRegistry codecRegistry, SpELExpressionEvaluator evaluator) {
|
||||
|
||||
Assert.notNull(source, "Source Row must not be null");
|
||||
Assert.notNull(codecRegistry, "CodecRegistry must not be null");
|
||||
Assert.notNull(evaluator, "SpELExpressionEvaluator must not be null");
|
||||
|
||||
this.reader = new ColumnReader(source);
|
||||
this.reader = new ColumnReader(source, codecRegistry);
|
||||
this.evaluator = evaluator;
|
||||
}
|
||||
|
||||
@@ -59,11 +63,11 @@ public class BasicCassandraRowValueProvider implements CassandraRowValueProvider
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @param evaluator must not be {@literal null}.
|
||||
* @deprecated since 2.1, use {@link #BasicCassandraRowValueProvider(Row, SpELExpressionEvaluator)}
|
||||
* @deprecated since 2.1, use {@link #BasicCassandraRowValueProvider(Row, CodecRegistry, SpELExpressionEvaluator)}
|
||||
*/
|
||||
@Deprecated
|
||||
public BasicCassandraRowValueProvider(Row source, DefaultSpELExpressionEvaluator evaluator) {
|
||||
this(source, (SpELExpressionEvaluator) evaluator);
|
||||
this(source, CodecRegistry.DEFAULT_INSTANCE, evaluator);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -38,14 +38,16 @@ import com.datastax.driver.core.TypeCodec;
|
||||
public class ColumnReader {
|
||||
|
||||
private final Row row;
|
||||
private final ColumnDefinitions columns;
|
||||
|
||||
private final CodecRegistry codecRegistry;
|
||||
|
||||
public ColumnReader(Row row) {
|
||||
private final ColumnDefinitions columns;
|
||||
|
||||
public ColumnReader(Row row, CodecRegistry codecRegistry) {
|
||||
|
||||
this.row = row;
|
||||
this.codecRegistry = codecRegistry;
|
||||
this.columns = row.getColumnDefinitions();
|
||||
this.codecRegistry = CodecRegistry.DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -153,7 +153,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter
|
||||
}
|
||||
|
||||
private CodecRegistry getCodecRegistry() {
|
||||
return CodecRegistry.DEFAULT_INSTANCE;
|
||||
return getMappingContext().getCodecRegistry();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -251,7 +251,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter
|
||||
|
||||
private <S> S readEntityFromRow(CassandraPersistentEntity<S> entity, Row row) {
|
||||
return doReadEntity(entity, row,
|
||||
expressionEvaluator -> new BasicCassandraRowValueProvider(row, expressionEvaluator));
|
||||
expressionEvaluator -> new BasicCassandraRowValueProvider(row, getCodecRegistry(), expressionEvaluator));
|
||||
}
|
||||
|
||||
private <S> S readEntityFromTuple(CassandraPersistentEntity<S> entity, TupleValue tupleValue) {
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.datastax.driver.core.CodecRegistry;
|
||||
import com.datastax.driver.core.DataType;
|
||||
import com.datastax.driver.core.DataType.Name;
|
||||
import com.datastax.driver.core.TupleType;
|
||||
@@ -81,6 +82,8 @@ public class CassandraMappingContext
|
||||
|
||||
private @Nullable UserTypeResolver userTypeResolver;
|
||||
|
||||
private CodecRegistry codecRegistry = CodecRegistry.DEFAULT_INSTANCE;
|
||||
|
||||
// caches
|
||||
private final Map<CqlIdentifier, Set<CassandraPersistentEntity<?>>> entitySetsByTableName = new HashMap<>();
|
||||
|
||||
@@ -135,7 +138,6 @@ public class CassandraMappingContext
|
||||
}
|
||||
|
||||
processMappingOverrides(entity, entityMapping);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -159,7 +161,7 @@ public class CassandraMappingContext
|
||||
|
||||
CassandraPersistentProperty property = entity.getRequiredPersistentProperty(mapping.getPropertyName());
|
||||
|
||||
boolean forceQuote = Boolean.valueOf(mapping.getForceQuote());
|
||||
boolean forceQuote = Boolean.parseBoolean(mapping.getForceQuote());
|
||||
|
||||
property.setForceQuote(forceQuote);
|
||||
|
||||
@@ -226,6 +228,24 @@ public class CassandraMappingContext
|
||||
return Collections.unmodifiableSet(this.userDefinedTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link CodecRegistry}.
|
||||
*
|
||||
* @param codecRegistry must not be {@literal null}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public void setCodecRegistry(CodecRegistry codecRegistry) {
|
||||
|
||||
Assert.notNull(codecRegistry, "CodecRegistry must not be null");
|
||||
|
||||
this.codecRegistry = codecRegistry;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public CodecRegistry getCodecRegistry() {
|
||||
return this.codecRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link TupleTypeFactory}.
|
||||
*
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.data.repository.query.ResultProcessor;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.CodecRegistry;
|
||||
import com.datastax.driver.core.Statement;
|
||||
|
||||
/**
|
||||
@@ -46,6 +47,8 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup
|
||||
|
||||
private final CassandraOperations operations;
|
||||
|
||||
private final CodecRegistry codecRegistry;
|
||||
|
||||
private static CassandraConverter toConverter(CassandraOperations operations) {
|
||||
|
||||
Assert.notNull(operations, "CassandraOperations must not be null");
|
||||
@@ -69,6 +72,7 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup
|
||||
super(queryMethod, toMappingContext(operations));
|
||||
|
||||
this.operations = operations;
|
||||
this.codecRegistry = operations.getConverter().getMappingContext().getCodecRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +93,7 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup
|
||||
public Object execute(Object[] parameters) {
|
||||
|
||||
CassandraParameterAccessor parameterAccessor = new ConvertingParameterAccessor(toConverter(getOperations()),
|
||||
new CassandraParametersParameterAccessor(getQueryMethod(), parameters));
|
||||
new CassandraParametersParameterAccessor(getQueryMethod(), parameters), codecRegistry);
|
||||
|
||||
ResultProcessor resultProcessor = getQueryMethod().getResultProcessor().withDynamicProjection(parameterAccessor);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.cassandra.ReactiveResultSet;
|
||||
import org.springframework.data.cassandra.core.CassandraOperations;
|
||||
@@ -36,6 +37,7 @@ import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.ResultProcessor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.CodecRegistry;
|
||||
import com.datastax.driver.core.Statement;
|
||||
|
||||
/**
|
||||
@@ -50,6 +52,8 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository
|
||||
|
||||
private final ReactiveCassandraOperations operations;
|
||||
|
||||
private final CodecRegistry codecRegistry;
|
||||
|
||||
/**
|
||||
* Create a new {@link AbstractReactiveCassandraQuery} from the given {@link CassandraQueryMethod} and
|
||||
* {@link CassandraOperations}.
|
||||
@@ -62,6 +66,7 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository
|
||||
super(method, getRequiredMappingContext(operations));
|
||||
|
||||
this.operations = operations;
|
||||
this.codecRegistry = operations.getConverter().getMappingContext().getCodecRegistry();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -96,7 +101,7 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository
|
||||
parameters);
|
||||
|
||||
CassandraParameterAccessor convertingParameterAccessor = new ConvertingParameterAccessor(
|
||||
getRequiredConverter(getReactiveCassandraOperations()), parameterAccessor);
|
||||
getRequiredConverter(getReactiveCassandraOperations()), parameterAccessor, codecRegistry);
|
||||
|
||||
Statement statement = createQuery(convertingParameterAccessor);
|
||||
|
||||
|
||||
@@ -52,10 +52,14 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
|
||||
|
||||
private final CassandraParameterAccessor delegate;
|
||||
|
||||
ConvertingParameterAccessor(CassandraConverter converter, CassandraParameterAccessor delegate) {
|
||||
private final CodecRegistry codecRegistry;
|
||||
|
||||
ConvertingParameterAccessor(CassandraConverter converter, CassandraParameterAccessor delegate,
|
||||
CodecRegistry codecRegistry) {
|
||||
|
||||
this.converter = converter;
|
||||
this.delegate = delegate;
|
||||
this.codecRegistry = codecRegistry;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -170,7 +174,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor {
|
||||
|
||||
if (this.delegate.findCassandraType(index) != null) {
|
||||
|
||||
TypeCodec<?> typeCodec = CodecRegistry.DEFAULT_INSTANCE.codecFor(getDataType(index, property));
|
||||
TypeCodec<?> typeCodec = codecRegistry.codecFor(getDataType(index, property));
|
||||
|
||||
if (typeCodec.getJavaType().getType() instanceof Class<?>) {
|
||||
return ClassTypeInformation.from((Class<?>) typeCodec.getJavaType().getType());
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.core.convert;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.BDDMockito.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -27,6 +26,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import org.springframework.data.cassandra.core.cql.CqlIdentifier;
|
||||
|
||||
import com.datastax.driver.core.CodecRegistry;
|
||||
import com.datastax.driver.core.ColumnDefinitions;
|
||||
import com.datastax.driver.core.Row;
|
||||
|
||||
@@ -51,7 +51,7 @@ public class ColumnReaderUnitTests {
|
||||
public void setup() {
|
||||
|
||||
when(row.getColumnDefinitions()).thenReturn(columnDefinitions);
|
||||
underTest = new ColumnReader(row);
|
||||
underTest = new ColumnReader(row, CodecRegistry.DEFAULT_INSTANCE);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@@ -62,8 +62,7 @@ public class ColumnReaderUnitTests {
|
||||
try {
|
||||
underTest.get(NON_EXISTENT_COLUMN);
|
||||
fail("Expected illegal argument exception");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
} catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Column [%s] does not exist in table", NON_EXISTENT_COLUMN);
|
||||
assertThat(expected).hasNoCause();
|
||||
@@ -79,8 +78,7 @@ public class ColumnReaderUnitTests {
|
||||
|
||||
try {
|
||||
underTest.get(CqlIdentifier.of(NON_EXISTENT_COLUMN));
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
} catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Column [%s] does not exist in table", NON_EXISTENT_COLUMN);
|
||||
assertThat(expected).hasNoCause();
|
||||
@@ -96,8 +94,7 @@ public class ColumnReaderUnitTests {
|
||||
|
||||
try {
|
||||
underTest.get(CqlIdentifier.of(NON_EXISTENT_COLUMN), String.class);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
} catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("Column [%s] does not exist in table", NON_EXISTENT_COLUMN);
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraType;
|
||||
@@ -35,6 +36,7 @@ import org.springframework.data.cassandra.repository.query.ConvertingParameterAc
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import com.datastax.driver.core.CodecRegistry;
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
/**
|
||||
@@ -57,13 +59,15 @@ public class ConvertingParameterAccessorUnitTests {
|
||||
|
||||
this.converter = new MappingCassandraConverter();
|
||||
this.converter.afterPropertiesSet();
|
||||
this.convertingParameterAccessor = new ConvertingParameterAccessor(converter, mockParameterAccessor);
|
||||
this.convertingParameterAccessor = new ConvertingParameterAccessor(converter, mockParameterAccessor,
|
||||
CodecRegistry.DEFAULT_INSTANCE);
|
||||
}
|
||||
|
||||
@Test // DATACASS-296
|
||||
public void shouldReturnNullBindableValue() {
|
||||
|
||||
ConvertingParameterAccessor accessor = new ConvertingParameterAccessor(converter, mockParameterAccessor);
|
||||
ConvertingParameterAccessor accessor = new ConvertingParameterAccessor(converter, mockParameterAccessor,
|
||||
CodecRegistry.DEFAULT_INSTANCE);
|
||||
|
||||
assertThat(accessor.getBindableValue(0)).isNull();
|
||||
}
|
||||
@@ -74,7 +78,8 @@ public class ConvertingParameterAccessorUnitTests {
|
||||
|
||||
when(mockParameterAccessor.getBindableValue(0)).thenReturn("hello");
|
||||
|
||||
ConvertingParameterAccessor accessor = new ConvertingParameterAccessor(converter, mockParameterAccessor);
|
||||
ConvertingParameterAccessor accessor = new ConvertingParameterAccessor(converter, mockParameterAccessor,
|
||||
CodecRegistry.DEFAULT_INSTANCE);
|
||||
|
||||
assertThat(accessor.getBindableValue(0)).isEqualTo((Object) "hello");
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.datastax.driver.core.CodecRegistry;
|
||||
import com.datastax.driver.core.ConsistencyLevel;
|
||||
import com.datastax.driver.core.Statement;
|
||||
import com.datastax.driver.core.UDTValue;
|
||||
@@ -248,7 +249,8 @@ public class PartTreeCassandraQueryUnitTests {
|
||||
CassandraParameterAccessor accessor = new CassandraParametersParameterAccessor(partTreeQuery.getQueryMethod(),
|
||||
args);
|
||||
|
||||
return partTreeQuery.createQuery(new ConvertingParameterAccessor(mockCassandraOperations.getConverter(), accessor));
|
||||
return partTreeQuery.createQuery(new ConvertingParameterAccessor(mockCassandraOperations.getConverter(), accessor,
|
||||
CodecRegistry.DEFAULT_INSTANCE));
|
||||
}
|
||||
|
||||
private PartTreeCassandraQuery createQueryForMethod(Class<?> repositoryInterface, String methodName,
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.datastax.driver.core.CodecRegistry;
|
||||
import com.datastax.driver.core.ConsistencyLevel;
|
||||
import com.datastax.driver.core.Statement;
|
||||
|
||||
@@ -174,7 +175,8 @@ public class ReactivePartTreeCassandraQueryUnitTests {
|
||||
CassandraParameterAccessor accessor = new CassandraParametersParameterAccessor(partTreeQuery.getQueryMethod(),
|
||||
args);
|
||||
|
||||
return partTreeQuery.createQuery(new ConvertingParameterAccessor(mockCassandraOperations.getConverter(), accessor));
|
||||
return partTreeQuery.createQuery(new ConvertingParameterAccessor(mockCassandraOperations.getConverter(), accessor,
|
||||
CodecRegistry.DEFAULT_INSTANCE));
|
||||
}
|
||||
|
||||
private ReactivePartTreeCassandraQuery createQueryForMethod(Class<?> repositoryInterface, String methodName,
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.springframework.data.repository.query.QueryCreationException;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.datastax.driver.core.CodecRegistry;
|
||||
import com.datastax.driver.core.ConsistencyLevel;
|
||||
import com.datastax.driver.core.DataType;
|
||||
import com.datastax.driver.core.SimpleStatement;
|
||||
@@ -326,7 +327,8 @@ public class StringBasedCassandraQueryUnitTests {
|
||||
|
||||
StringBasedCassandraQuery cassandraQuery = getQueryMethod("findByCreatedDate", LocalDate.class);
|
||||
CassandraParameterAccessor accessor = new ConvertingParameterAccessor(converter,
|
||||
new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), LocalDate.of(2010, 7, 4)));
|
||||
new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), LocalDate.of(2010, 7, 4)),
|
||||
CodecRegistry.DEFAULT_INSTANCE);
|
||||
|
||||
SimpleStatement actual = cassandraQuery.createQuery(accessor);
|
||||
|
||||
@@ -345,7 +347,8 @@ public class StringBasedCassandraQueryUnitTests {
|
||||
|
||||
StringBasedCassandraQuery cassandraQuery = getQueryMethod("findByMainAddress", AddressType.class);
|
||||
CassandraParameterAccessor accessor = new ConvertingParameterAccessor(converter,
|
||||
new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), new AddressType()));
|
||||
new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), new AddressType()),
|
||||
CodecRegistry.DEFAULT_INSTANCE);
|
||||
|
||||
SimpleStatement stringQuery = cassandraQuery.createQuery(accessor);
|
||||
|
||||
@@ -358,7 +361,8 @@ public class StringBasedCassandraQueryUnitTests {
|
||||
|
||||
StringBasedCassandraQuery cassandraQuery = getQueryMethod("findByMainAddress", UDTValue.class);
|
||||
CassandraParameterAccessor accessor = new ConvertingParameterAccessor(converter,
|
||||
new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), udtValue));
|
||||
new CassandraParametersParameterAccessor(cassandraQuery.getQueryMethod(), udtValue),
|
||||
CodecRegistry.DEFAULT_INSTANCE);
|
||||
|
||||
SimpleStatement stringQuery = cassandraQuery.createQuery(accessor);
|
||||
|
||||
|
||||
@@ -48,7 +48,8 @@ class StubParameterAccessor implements CassandraParameterAccessor {
|
||||
* @return
|
||||
*/
|
||||
public static ConvertingParameterAccessor getAccessor(CassandraConverter converter, Object... parameters) {
|
||||
return new ConvertingParameterAccessor(converter, new StubParameterAccessor(parameters));
|
||||
return new ConvertingParameterAccessor(converter, new StubParameterAccessor(parameters),
|
||||
CodecRegistry.DEFAULT_INSTANCE);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
Reference in New Issue
Block a user