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:
Mark Paluch
2019-07-11 16:03:45 +02:00
parent 24fcea3f92
commit 1fcbbc8fb2
14 changed files with 86 additions and 35 deletions

View File

@@ -160,6 +160,7 @@ public abstract class AbstractCassandraConfiguration extends AbstractClusterConf
mappingContext.setCustomConversions(customConversions);
mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
mappingContext.setCodecRegistry(cluster.getConfiguration().getCodecRegistry());
return mappingContext;
}

View File

@@ -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)

View File

@@ -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;
}
/**

View File

@@ -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) {

View File

@@ -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}.
*

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());

View File

@@ -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();

View File

@@ -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");
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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);

View File

@@ -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")