From 6ebbb894c683a0763a7e56b72a4d42e474365a3c Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 3 Jul 2017 14:41:13 +0200 Subject: [PATCH] DATACASS-473 - Adapt to API changes in mapping subsystem. --- ...assandraPersistentEntitySchemaCreator.java | 23 +- .../cassandra/core/CassandraTemplate.java | 3 +- .../BasicCassandraRowValueProvider.java | 12 +- .../core/convert/CassandraConverter.java | 10 +- .../convert/CassandraUDTValueProvider.java | 12 +- .../convert/MappingCassandraConverter.java | 333 ++++++++---------- .../cassandra/core/convert/QueryMapper.java | 20 +- .../cassandra/core/convert/UpdateMapper.java | 50 ++- .../BasicCassandraPersistentEntity.java | 20 +- ...andraPersistentEntityMetadataVerifier.java | 6 +- .../BasicCassandraPersistentProperty.java | 63 ++-- .../core/mapping/CassandraMappingContext.java | 56 +-- ...andraPersistentEntityMetadataVerifier.java | 3 +- .../mapping/CassandraPersistentProperty.java | 4 +- ...CassandraPersistentPropertyComparator.java | 13 +- .../CassandraUserTypePersistentEntity.java | 12 +- ...andraPersistentEntityMetadataVerifier.java | 2 +- ...PrimaryKeyClassEntityMetadataVerifier.java | 6 +- .../mapping/VerifierMappingExceptions.java | 2 +- .../query/CassandraQueryMethod.java | 7 +- .../query/ConvertingParameterAccessor.java | 42 ++- .../query/DtoInstantiatingConverter.java | 24 +- .../support/IdInterfaceException.java | 2 +- .../support/IdInterfaceExceptions.java | 2 +- .../support/IdInterfaceValidator.java | 2 +- .../MappingCassandraEntityInformation.java | 20 +- .../support/SimpleCassandraRepository.java | 3 +- ...istentEntityMetadataVerifierUnitTests.java | 2 +- ...cCassandraPersistentPropertyUnitTests.java | 2 +- .../CassandraMappingContextUnitTests.java | 11 +- ...istentEntityMetadataVerifierUnitTests.java | 2 +- ...yClassEntityMetadataVerifierUnitTests.java | 2 +- .../ConvertingParameterAccessorUnitTests.java | 8 +- 33 files changed, 385 insertions(+), 394 deletions(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java index 15cf334ec..dfef330f7 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java @@ -25,14 +25,15 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntity; 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.cql.core.CqlIdentifier; import org.springframework.data.cql.core.generator.CreateTableCqlGenerator; import org.springframework.data.cql.core.generator.CreateUserTypeCqlGenerator; import org.springframework.data.cql.core.keyspace.CreateTableSpecification; import org.springframework.data.cql.core.keyspace.CreateUserTypeSpecification; -import org.springframework.data.util.Optionals; import org.springframework.util.Assert; /** @@ -136,7 +137,6 @@ public class CassandraPersistentEntitySchemaCreator { .filter(created::add).map(identifier -> mappingContext .getCreateUserTypeSpecificationFor(byTableName.get(identifier)).ifNotExists(ifNotExists)) .collect(Collectors.toList())); - }); return specifications; @@ -144,14 +144,17 @@ public class CassandraPersistentEntitySchemaCreator { private void visitUserTypes(CassandraPersistentEntity entity, final Set seen) { - entity.getPersistentProperties() // - .map(mappingContext::getPersistentEntity) // - .flatMap(Optionals::toStream) // - .filter(CassandraPersistentEntity::isUserDefinedType).forEach(persistentEntity -> { - if (seen.add(persistentEntity.getTableName())) { - visitUserTypes(persistentEntity, seen); - } - }); + for (CassandraPersistentProperty property : entity) { + BasicCassandraPersistentEntity persistentEntity = mappingContext.getPersistentEntity(property); + + if (persistentEntity == null) { + continue; + } + + if (persistentEntity.isUserDefinedType() && seen.add(persistentEntity.getTableName())) { + visitUserTypes(persistentEntity, seen); + } + } } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java index 34e650b5b..f0368cd22 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java @@ -404,8 +404,7 @@ public class CassandraTemplate implements CassandraOperations { CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(entityClass); - CassandraPersistentProperty idProperty = entity.getIdProperty().orElseThrow(() -> new IllegalArgumentException( - String.format("Entity class [%s] has no primary key", entityClass.getName()))); + CassandraPersistentProperty idProperty = entity.getRequiredIdProperty(); if (idProperty.isCompositePrimaryKey()) { diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/BasicCassandraRowValueProvider.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/BasicCassandraRowValueProvider.java index b9fcb6d9a..ea86930da 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/BasicCassandraRowValueProvider.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/BasicCassandraRowValueProvider.java @@ -15,8 +15,6 @@ */ package org.springframework.data.cassandra.core.convert; -import java.util.Optional; - import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator; import org.springframework.data.mapping.model.SpELExpressionEvaluator; @@ -59,14 +57,14 @@ public class BasicCassandraRowValueProvider implements CassandraRowValueProvider */ @Override @SuppressWarnings("unchecked") - public Optional getPropertyValue(CassandraPersistentProperty property) { + public T getPropertyValue(CassandraPersistentProperty property) { - Optional spelExpression = property.getSpelExpression(); - if (spelExpression.isPresent()) { - return spelExpression.flatMap(s -> Optional.ofNullable(evaluator.evaluate(s))); + String spelExpression = property.getSpelExpression(); + if (spelExpression != null) { + return evaluator.evaluate(spelExpression); } - return Optional.ofNullable((T) reader.get(property.getColumnName())); + return (T) reader.get(property.getColumnName()); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraConverter.java index 9a6c8969f..305fc7355 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraConverter.java @@ -15,8 +15,6 @@ */ package org.springframework.data.cassandra.core.convert; -import java.util.Optional; - import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity; import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; @@ -67,21 +65,21 @@ public interface CassandraConverter /** * Converts the given object into a value Cassandra will be able to store natively in a column. * - * @param obj {@link Object} to convert; must not be {@literal null}. + * @param value {@link Object} to convert; must not be {@literal null}. * @return the result of the conversion. * @since 2.0 */ - Optional convertToColumnType(Optional obj); + Object convertToColumnType(Object value); /** * Converts the given object into a value Cassandra will be able to store natively in a column. * - * @param obj {@link Object} to convert; must not be {@literal null}. + * @param value {@link Object} to convert; must not be {@literal null}. * @param typeInformation {@link TypeInformation} used to describe the object type; may be {@literal null}. * @return the result of the conversion. * @since 1.5 */ - Optional convertToColumnType(Optional obj, TypeInformation typeInformation); + Object convertToColumnType(Object value, TypeInformation typeInformation); /** * Converts and writes a {@code source} object into a {@code sink} using the given {@link CassandraPersistentEntity}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraUDTValueProvider.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraUDTValueProvider.java index 9f01a5348..2503fd478 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraUDTValueProvider.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/CassandraUDTValueProvider.java @@ -15,8 +15,6 @@ */ package org.springframework.data.cassandra.core.convert; -import java.util.Optional; - import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator; import org.springframework.data.mapping.model.SpELExpressionEvaluator; @@ -64,17 +62,17 @@ public class CassandraUDTValueProvider implements CassandraValueProvider { * @see org.springframework.data.mapping.model.PropertyValueProvider#getPropertyValue(org.springframework.data.mapping.PersistentProperty) */ @SuppressWarnings("unchecked") - public Optional getPropertyValue(CassandraPersistentProperty property) { + public T getPropertyValue(CassandraPersistentProperty property) { - Optional spelExpression = property.getSpelExpression(); - if (spelExpression.isPresent()) { - return spelExpression.flatMap(s -> Optional.ofNullable(evaluator.evaluate(s))); + String spelExpression = property.getSpelExpression(); + if (spelExpression != null) { + return evaluator.evaluate(spelExpression); } String name = property.getColumnName().toCql(); DataType fieldType = udtValue.getType().getFieldType(name); - return Optional.ofNullable(udtValue.get(name, codecRegistry.codecFor(fieldType))); + return udtValue.get(name, codecRegistry.codecFor(fieldType)); } /* (non-Javadoc) 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 e3c048d1f..e6aa89ad1 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 @@ -24,7 +24,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Optional; +import java.util.Map.Entry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,11 +43,11 @@ import org.springframework.data.cassandra.core.mapping.CassandraType; import org.springframework.data.cassandra.repository.MapId; import org.springframework.data.cassandra.repository.MapIdentifiable; import org.springframework.data.convert.EntityInstantiator; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator; -import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider; import org.springframework.data.mapping.model.SpELContext; import org.springframework.data.util.ClassTypeInformation; @@ -171,7 +171,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter BasicCassandraRowValueProvider rowValueProvider = new BasicCassandraRowValueProvider(row, expressionEvaluator); PersistentEntityParameterValueProvider parameterValueProvider = new PersistentEntityParameterValueProvider<>( - entity, new MappingAndConvertingValueProvider(rowValueProvider), Optional.empty()); + entity, new MappingAndConvertingValueProvider(rowValueProvider), null); EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity); S instance = instantiator.createInstance(entity, parameterValueProvider); @@ -202,7 +202,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter private PersistentEntityParameterValueProvider getParameterValueProvider( CassandraPersistentEntity entity, CassandraValueProvider valueProvider) { return new PersistentEntityParameterValueProvider<>(entity, new MappingAndConvertingValueProvider(valueProvider), - Optional.empty()); + null); } protected void readPropertiesFromRow(CassandraPersistentEntity entity, CassandraRowValueProvider row, @@ -214,8 +214,9 @@ public class MappingCassandraConverter extends AbstractCassandraConverter protected void readProperties(CassandraPersistentEntity entity, CassandraValueProvider valueProvider, PersistentPropertyAccessor propertyAccessor) { - entity.getPersistentProperties().forEach( - property -> MappingCassandraConverter.this.readProperty(entity, property, valueProvider, propertyAccessor)); + for (CassandraPersistentProperty property : entity) { + MappingCassandraConverter.this.readProperty(entity, property, valueProvider, propertyAccessor); + } } protected void readProperty(CassandraPersistentEntity entity, CassandraPersistentProperty property, @@ -229,17 +230,17 @@ public class MappingCassandraConverter extends AbstractCassandraConverter if (property.isCompositePrimaryKey()) { CassandraPersistentEntity keyEntity = mappingContext.getRequiredPersistentEntity(property); - Optional optionalKey = propertyAccessor.getProperty(property); + Object key = propertyAccessor.getProperty(property); - if (!optionalKey.isPresent()) { - optionalKey = Optional.of(instantiatePrimaryKey(keyEntity, property, valueProvider)); + if (key == null) { + key = instantiatePrimaryKey(keyEntity, property, valueProvider); } // now recurse on using the key this time - optionalKey.ifPresent(key -> readProperties(keyEntity, valueProvider, getConvertingAccessor(key, keyEntity))); + readProperties(keyEntity, valueProvider, getConvertingAccessor(key, keyEntity)); // now that the key's properties have been populated, set the key property on the entity - propertyAccessor.setProperty(property, optionalKey); + propertyAccessor.setProperty(property, key); return; } @@ -273,32 +274,27 @@ public class MappingCassandraConverter extends AbstractCassandraConverter } /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.convert.CassandraConverter#convertToColumnType(java.util.Optional) + * @see org.springframework.data.cassandra.core.convert.CassandraConverter#convertToColumnType(java.lang.Object) */ @Override @SuppressWarnings("unchecked") - public Optional convertToColumnType(Optional obj) { - - return convertToColumnType(obj, obj.map(Object::getClass).map(ClassTypeInformation::from) - .orElse((ClassTypeInformation) ClassTypeInformation.OBJECT)); + public Object convertToColumnType(Object obj) { + return convertToColumnType(obj, ClassTypeInformation.from(obj.getClass())); } /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.convert.CassandraConverter#convertToColumnType(java.util.Optional, org.springframework.data.util.TypeInformation) + * @see org.springframework.data.cassandra.core.convert.CassandraConverter#convertToColumnType(java.lang.Object, org.springframework.data.util.TypeInformation) */ @Override - public Optional convertToColumnType(Optional obj, TypeInformation typeInformation) { + public Object convertToColumnType(Object value, TypeInformation typeInformation) { Assert.notNull(typeInformation, "TypeInformation must not be null"); - return obj.flatMap(object -> { + if (value == null) { + return null; + } - if (object.getClass().isArray()) { - return Optional.of(object); - } - - return getWriteValue(obj, typeInformation); - }); + return value.getClass().isArray() ? value : getWriteValue(value, typeInformation); } @Override @@ -357,9 +353,9 @@ public class MappingCassandraConverter extends AbstractCassandraConverter private void writeMapFromWrapper(final ConvertingPropertyAccessor accessor, final Map insert, CassandraPersistentEntity entity) { - entity.getPersistentProperties().forEach(property -> { + for (CassandraPersistentProperty property : entity) { - Optional value = getWriteValue(property, accessor); + Object value = getWriteValue(property, accessor); if (log.isDebugEnabled()) { log.debug("doWithProperties Property.type {}, Property.value {}", property.getType().getName(), value); @@ -372,26 +368,25 @@ public class MappingCassandraConverter extends AbstractCassandraConverter } CassandraPersistentEntity compositePrimaryKey = mappingContext.getRequiredPersistentEntity(property); - writeMapFromWrapper(getConvertingAccessor(value.orElse(null), compositePrimaryKey), insert, - compositePrimaryKey); + writeMapFromWrapper(getConvertingAccessor(value, compositePrimaryKey), insert, compositePrimaryKey); - return; + continue; } if (log.isDebugEnabled()) { log.debug("Adding map.entry [{}] - [{}]", property.getColumnName().toCql(), value); } - insert.put(property.getColumnName().toCql(), value.orElse(null)); - }); + insert.put(property.getColumnName().toCql(), value); + } } protected void writeInsertFromWrapper(final ConvertingPropertyAccessor accessor, final Insert insert, CassandraPersistentEntity entity) { - entity.getPersistentProperties().forEach(property -> { + for (CassandraPersistentProperty property : entity) { - Optional value = getWriteValue(property, accessor); + Object value = getWriteValue(property, accessor); if (log.isDebugEnabled()) { log.debug("doWithProperties Property.type {}, Property.value {}", property.getType().getName(), value); @@ -404,22 +399,21 @@ public class MappingCassandraConverter extends AbstractCassandraConverter } CassandraPersistentEntity compositePrimaryKey = mappingContext.getRequiredPersistentEntity(property); - writeInsertFromWrapper(getConvertingAccessor(value.orElse(null), compositePrimaryKey), insert, - compositePrimaryKey); + writeInsertFromWrapper(getConvertingAccessor(value, compositePrimaryKey), insert, compositePrimaryKey); - return; + continue; } - if (!value.isPresent()) { - return; + if (value == null) { + continue; } if (log.isDebugEnabled()) { log.debug("Adding insert.value [{}] - [{}]", property.getColumnName().toCql(), value); } - insert.value(property.getColumnName().toCql(), value.orElse(null)); - }); + insert.value(property.getColumnName().toCql(), value); + } } protected void writeUpdateFromObject(final Object object, final Update update, CassandraPersistentEntity entity) { @@ -429,25 +423,24 @@ public class MappingCassandraConverter extends AbstractCassandraConverter protected void writeUpdateFromWrapper(final ConvertingPropertyAccessor accessor, final Update update, final CassandraPersistentEntity entity) { - entity.getPersistentProperties().forEach(property -> { + for (CassandraPersistentProperty property : entity) { - Optional value = getWriteValue(property, accessor); + Object value = getWriteValue(property, accessor); if (property.isCompositePrimaryKey()) { CassandraPersistentEntity compositePrimaryKey = mappingContext.getRequiredPersistentEntity(property); - writeUpdateFromWrapper(getConvertingAccessor(value.orElse(null), compositePrimaryKey), update, - compositePrimaryKey); - return; + writeUpdateFromWrapper(getConvertingAccessor(value, compositePrimaryKey), update, compositePrimaryKey); + continue; } if (isPrimaryKeyPart(property)) { - update.where(QueryBuilder.eq(property.getColumnName().toCql(), value.orElse(null))); + update.where(QueryBuilder.eq(property.getColumnName().toCql(), value)); } else { - update.with(QueryBuilder.set(property.getColumnName().toCql(), value.orElse(null))); + update.with(QueryBuilder.set(property.getColumnName().toCql(), value)); } - }); + } } protected void writeSelectWhereFromObject(final Object object, final Select.Where where, @@ -463,9 +456,9 @@ public class MappingCassandraConverter extends AbstractCassandraConverter protected void writeUDTValueWhereFromObject(final ConvertingPropertyAccessor accessor, final UDTValue udtValue, CassandraPersistentEntity entity) { - entity.getPersistentProperties().forEach(property -> { + for (CassandraPersistentProperty property : entity) { - Optional value = getWriteValue(property, accessor); + Object value = getWriteValue(property, accessor); if (log.isDebugEnabled()) { log.debug("writeUDTValueWhereFromObject Property.type {}, Property.value {}", property.getType().getName(), @@ -478,8 +471,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter TypeCodec typeCodec = CodecRegistry.DEFAULT_INSTANCE.codecFor(getMappingContext().getDataType(property)); - udtValue.set(property.getColumnName().toCql(), value.orElse(null), typeCodec); - }); + udtValue.set(property.getColumnName().toCql(), value, typeCodec); + } } @SuppressWarnings("unchecked") @@ -490,31 +483,33 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Object id = extractId(source, entity); Assert.notNull(id, String.format("No Id value found in object %s", source)); - Optional optionalIdProperty = entity.getIdProperty(); + CassandraPersistentProperty idProperty = entity.getIdProperty(); + CassandraPersistentProperty compositeIdProperty = null; - Optional optionalCompositeIdProperty = optionalIdProperty - .filter(CassandraPersistentProperty::isCompositePrimaryKey); + if (idProperty != null && idProperty.isCompositePrimaryKey()) { + compositeIdProperty = idProperty; + } if (id instanceof MapId) { // FIXME: Generics - CassandraPersistentEntity whereEntity = optionalCompositeIdProperty // - .map(it -> (CassandraPersistentEntity) mappingContext.getRequiredPersistentEntity(it)) // - .orElse((CassandraPersistentEntity) entity); + CassandraPersistentEntity whereEntity = compositeIdProperty != null + ? mappingContext.getRequiredPersistentEntity(compositeIdProperty) : entity; return getWhereClauses((MapId) id, whereEntity); } - CassandraPersistentProperty idProperty = optionalIdProperty - .orElseThrow(() -> new InvalidDataAccessApiUsageException( - String.format("Cannot obtain where clauses for entity [%s] using [%s]", entity.getName(), source))); + if (idProperty == null) { + throw new InvalidDataAccessApiUsageException( + String.format("Cannot obtain where clauses for entity [%s] using [%s]", entity.getName(), source)); + } - if (optionalCompositeIdProperty.isPresent()) { + if (compositeIdProperty != null) { - CassandraPersistentProperty compositeIdProperty = optionalCompositeIdProperty - .filter(p -> ClassUtils.isAssignableValue(p.getType(), id)) - .orElseThrow(() -> new InvalidDataAccessApiUsageException( - String.format("Cannot use [%s] as composite Id for [%s]", id, entity.getName()))); + if (!ClassUtils.isAssignableValue(compositeIdProperty.getType(), id)) { + throw new InvalidDataAccessApiUsageException( + String.format("Cannot use [%s] as composite Id for [%s]", id, entity.getName())); + } CassandraPersistentEntity compositePrimaryKey = mappingContext .getRequiredPersistentEntity(compositeIdProperty); @@ -524,8 +519,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Class targetType = getTargetType(idProperty); if (getConversionService().canConvert(id.getClass(), targetType)) { - return Collections.singleton(QueryBuilder.eq(idProperty.getColumnName().toCql(), - getPotentiallyConvertedSimpleValue(Optional.of(id), (Class) targetType).orElse(null))); + return Collections.singleton( + QueryBuilder.eq(idProperty.getColumnName().toCql(), getPotentiallyConvertedSimpleValue(id, targetType))); } return Collections.singleton(QueryBuilder.eq(idProperty.getColumnName().toCql(), id)); @@ -552,11 +547,12 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Collection clauses = new ArrayList<>(); - entity.getPersistentProperties().forEach(property -> { + for (CassandraPersistentProperty property : entity) { + TypeCodec codec = getCodec(property); - Optional value = accessor.getProperty(property, codec.getJavaType().getRawType()); - clauses.add(QueryBuilder.eq(property.getColumnName().toCql(), value.orElse(null))); - }); + Object value = accessor.getProperty(property, codec.getJavaType().getRawType()); + clauses.add(QueryBuilder.eq(property.getColumnName().toCql(), value)); + } return clauses; } @@ -569,15 +565,15 @@ public class MappingCassandraConverter extends AbstractCassandraConverter for (Entry entry : id.entrySet()) { - Optional lookup = entity.getPersistentProperty(entry.getKey()); + CassandraPersistentProperty persistentProperty = entity.getPersistentProperty(entry.getKey()); - CassandraPersistentProperty persistentProperty = lookup - .orElseThrow(() -> new IllegalArgumentException(String.format( - "MapId contains references [%s] that is an unknown property of [%s]", entry.getKey(), entity.getName()))); + if (persistentProperty == null) { + throw new IllegalArgumentException(String.format( + "MapId contains references [%s] that is an unknown property of [%s]", entry.getKey(), entity.getName())); + } - Optional writeValue = getWriteValue(Optional.ofNullable(entry.getValue()), - persistentProperty.getTypeInformation()); - clauses.add(QueryBuilder.eq(persistentProperty.getColumnName().toCql(), writeValue.orElse(null))); + Object writeValue = getWriteValue(entry.getValue(), persistentProperty.getTypeInformation()); + clauses.add(QueryBuilder.eq(persistentProperty.getColumnName().toCql(), writeValue)); } return clauses; @@ -600,23 +596,25 @@ public class MappingCassandraConverter extends AbstractCassandraConverter return ((MapIdentifiable) object).getMapId(); } - Optional optionalIdProperty = entity.getIdProperty(); + CassandraPersistentProperty idProperty = entity.getIdProperty(); - if (optionalIdProperty.isPresent()) { + if (idProperty != null) { // TODO: NullId - CassandraPersistentProperty idProperty = optionalIdProperty.get(); return accessor.getProperty(idProperty, idProperty.isCompositePrimaryKey() ? (Class) idProperty.getType() - : (Class) getTargetType(idProperty)).orElse(null); + : (Class) getTargetType(idProperty)); } // if the class doesn't have an id property, then it's using MapId final MapId id = id(); - entity.getPersistentProperties() // - .filter(CassandraPersistentProperty::isPrimaryKeyColumn) // - .forEach(property -> { - id.with(property.getName(), getWriteValue(property, accessor).orElse(null)); - }); + for (CassandraPersistentProperty property : entity) { + + if (!property.isPrimaryKeyColumn()) { + continue; + } + + id.with(property.getName(), getWriteValue(property, accessor)); + } return id; } @@ -650,7 +648,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter return getCustomConversions().getCustomWriteTarget(property.getType()).orElseGet(() -> { - if (property.findAnnotation(CassandraType.class).isPresent()) { + if (property.isAnnotationPresent(CassandraType.class)) { return getPropertyTargetType(property); } @@ -687,8 +685,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter * @return the return value, may be {@literal null}. */ @SuppressWarnings("unchecked") - private Optional getWriteValue(CassandraPersistentProperty property, ConvertingPropertyAccessor accessor) { - return getWriteValue(accessor.getProperty(property, (Class) getTargetType(property)), + private T getWriteValue(CassandraPersistentProperty property, ConvertingPropertyAccessor accessor) { + return (T) getWriteValue(accessor.getProperty(property, (Class) getTargetType(property)), property.getTypeInformation()); } @@ -696,38 +694,34 @@ public class MappingCassandraConverter extends AbstractCassandraConverter * Retrieve the value from {@code value} applying the given {@link TypeInformation} and perform optionally a * conversion of collection element types. * - * @param optional the value, may be {@literal null}. + * @param value the value, may be {@literal null}. * @param typeInformation the type information. * @return the return value, may be {@literal null}. */ @SuppressWarnings("unchecked") - private Optional getWriteValue(Optional optional, TypeInformation typeInformation) { + private Object getWriteValue(Object value, TypeInformation typeInformation) { - if (!optional.isPresent()) { - return Optional.empty(); + if (value == null) { + return null; } - I value = optional.get(); - - Class requestedTargetType = Optional.ofNullable(typeInformation).map(typeInfo -> (Class) typeInfo.getType()) - .orElse(null); + Class requestedTargetType = typeInformation != null ? typeInformation.getType() : Object.class; if (getCustomConversions().hasCustomWriteTarget(value.getClass(), requestedTargetType)) { - return Optional.ofNullable((O) getConversionService().convert(value, getCustomConversions() - .getCustomWriteTarget(value.getClass(), requestedTargetType).orElse(requestedTargetType))); + return getConversionService().convert(value, getCustomConversions() + .getCustomWriteTarget(value.getClass(), requestedTargetType).orElse(requestedTargetType)); } if (getCustomConversions().hasCustomWriteTarget(value.getClass())) { - return Optional.ofNullable((O) getConversionService().convert(value, - getCustomConversions().getCustomWriteTarget(value.getClass()).get())); + return getConversionService().convert(value, getCustomConversions().getCustomWriteTarget(value.getClass()).get()); } if (getCustomConversions().isSimpleType(value.getClass())) { - return getPotentiallyConvertedSimpleValue(optional, requestedTargetType); + return getPotentiallyConvertedSimpleValue(value, requestedTargetType); } - TypeInformation type = Optional.ofNullable(typeInformation) - .orElseGet(() -> ClassTypeInformation.from((Class) value.getClass())); + TypeInformation type = typeInformation != null ? typeInformation + : ClassTypeInformation.from((Class) value.getClass()); TypeInformation actualType = type.getActualType(); @@ -736,60 +730,54 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Collection original = (Collection) value; Collection converted = CollectionFactory.createCollection(getCollectionType(type), original.size()); - original.stream().map(element -> convertToColumnType(Optional.ofNullable(element), actualType).orElse(null)) - .forEach(converted::add); + for (Object element : original) { + converted.add(convertToColumnType(element, actualType)); + } - return Optional.of((O) converted); + return converted; } - Optional> optionalUdt = getMappingContext() - .getPersistentEntity(actualType.getType()).filter(CassandraPersistentEntity::isUserDefinedType); + BasicCassandraPersistentEntity entity = getMappingContext().getPersistentEntity(actualType.getType()); - if (optionalUdt.isPresent()) { + if (entity != null && entity.isUserDefinedType()) { - return optionalUdt.map(persistentEntity -> { + UDTValue udtValue = entity.getUserType().newValue(); - UDTValue udtValue = persistentEntity.getUserType().newValue(); - - write(value, udtValue, persistentEntity); - - return (O) udtValue; - }); + write(value, udtValue, entity); + return udtValue; } - return (Optional) optional; + return value; } /** * Performs special enum handling or simply returns the value as is. * - * @param optionalValue may be {@literal null}. + * @param value may be {@literal null}. * @param requestedTargetType must not be {@literal null}. * @see CassandraType */ @SuppressWarnings("unchecked") - private Optional getPotentiallyConvertedSimpleValue(Optional optionalValue, - Class requestedTargetType) { + private Object getPotentiallyConvertedSimpleValue(Object value, Class requestedTargetType) { - if (optionalValue.isPresent()) { - - Object value = optionalValue.get(); - - // Cassandra has no default enum handling - convert it to either a String - // or, if requested, to a different type - if (Enum.class.isAssignableFrom(value.getClass())) { - if (requestedTargetType != null && !requestedTargetType.isEnum() - && getConversionService().canConvert(value.getClass(), requestedTargetType)) { - - return Optional.ofNullable(getConversionService().convert(value, requestedTargetType)); - } - - return Optional.of((O) ((Enum) value).name()); - } + if (value == null) { + return null; } - return (Optional) optionalValue; + // Cassandra has no default enum handling - convert it to either a String + // or, if requested, to a different type + if (Enum.class.isAssignableFrom(value.getClass())) { + if (requestedTargetType != null && !requestedTargetType.isEnum() + && getConversionService().canConvert(value.getClass(), requestedTargetType)) { + + return getConversionService().convert(value, requestedTargetType); + } + + return ((Enum) value).name(); + } + + return value; } /** @@ -848,53 +836,48 @@ public class MappingCassandraConverter extends AbstractCassandraConverter * @return the return value, may be {@literal null}. */ @SuppressWarnings("unchecked") - protected Optional getReadValue(CassandraValueProvider row, CassandraPersistentProperty property) { + protected Object getReadValue(CassandraValueProvider row, CassandraPersistentProperty property) { if (property.isCompositePrimaryKey()) { CassandraPersistentEntity keyEntity = mappingContext.getRequiredPersistentEntity(property); - return Optional.of((T) instantiatePrimaryKey(keyEntity, property, row)); + return instantiatePrimaryKey(keyEntity, property, row); } - Optional obj = row.getPropertyValue(property); + Object value = row.getPropertyValue(property); - if (!obj.isPresent()) { - return Optional.empty(); + if (value == null) { + return null; } if (getCustomConversions().hasCustomWriteTarget(property.getActualType()) && property.isCollectionLike()) { - if (obj.filter(it -> it instanceof Collection).isPresent()) { + if (value instanceof Collection) { - return obj.map(it -> { + Collection original = (Collection) value; - Collection original = (Collection) it; + Collection converted = CollectionFactory.createCollection(property.getType(), original.size()); - Collection converted = CollectionFactory.createCollection(property.getType(), original.size()); - - for (Object element : original) { - converted.add(getConversionService().convert(element, property.getActualType())); - } - - return (T) converted; - }); + for (Object element : original) { + converted.add(getConversionService().convert(element, property.getActualType())); + } + return converted; } } - if (property.isCollectionLike() && obj.filter(it -> it instanceof Collection).isPresent()) { - return obj.map(it -> (T) readCollectionOrArray(property.getTypeInformation(), (Collection) it)); + if (property.isCollectionLike() && value instanceof Collection) { + return readCollectionOrArray(property.getTypeInformation(), (Collection) value); } - Optional> persistentEntity = getMappingContext() - .getPersistentEntity(property.getActualType()).filter(CassandraPersistentEntity::isUserDefinedType); + BasicCassandraPersistentEntity persistentEntity = getMappingContext() + .getPersistentEntity(property.getActualType()); - if (persistentEntity.isPresent() && obj.filter(it -> it instanceof UDTValue).isPresent()) { - return persistentEntity.flatMap( - cassandraPersistentEntity -> obj.map(it -> (T) readEntityFromUdt(cassandraPersistentEntity, (UDTValue) it))); + if (persistentEntity != null && persistentEntity.isUserDefinedType() && value instanceof UDTValue) { + return readEntityFromUdt(persistentEntity, (UDTValue) value); } - return obj.flatMap(it -> Optional.of((T) getPotentiallyConvertedSimpleRead(it, property.getType()))); + return getPotentiallyConvertedSimpleRead(value, property.getType()); } /** @@ -911,8 +894,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Class collectionType = targetType.getType(); - Optional> componentType = targetType.getComponentType(); - Class rawComponentType = componentType.map(TypeInformation::getType).orElse((Class) List.class); + TypeInformation componentType = targetType.getComponentType(); + Class rawComponentType = componentType != null ? componentType.getType() : List.class; collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class; Collection items = targetType.getType().isArray() ? new ArrayList<>() @@ -922,17 +905,13 @@ public class MappingCassandraConverter extends AbstractCassandraConverter return getPotentiallyConvertedSimpleRead(items, collectionType); } - Optional> cassandraPersistentEntity = componentType - .flatMap(it -> getMappingContext().getPersistentEntity(it)) - .filter(CassandraPersistentEntity::isUserDefinedType); + BasicCassandraPersistentEntity entity = getMappingContext().getPersistentEntity(componentType); - if (cassandraPersistentEntity.isPresent()) { + if (entity != null && entity.isUserDefinedType()) { - cassandraPersistentEntity.ifPresent(persistentEntity -> { - for (Object udtValue : sourceValue) { - items.add(readEntityFromUdt(persistentEntity, (UDTValue) udtValue)); - } - }); + for (Object udtValue : sourceValue) { + items.add(readEntityFromUdt(entity, (UDTValue) udtValue)); + } } else { for (Object item : sourceValue) { @@ -971,8 +950,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter * @see org.springframework.data.mapping.model.PropertyValueProvider#getPropertyValue(org.springframework.data.mapping.PersistentProperty) */ @Override - public Optional getPropertyValue(CassandraPersistentProperty property) { - return getReadValue(parent, property); + public T getPropertyValue(CassandraPersistentProperty property) { + return (T) getReadValue(parent, property); } } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/QueryMapper.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/QueryMapper.java index 80ba87912..f11bd911a 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/QueryMapper.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/QueryMapper.java @@ -129,11 +129,11 @@ public class QueryMapper { "Cannot use composite primary key directly. Reference a property of the composite primary key"); }); - Optional value = Optional.ofNullable(predicate.getValue()); + Object value = predicate.getValue(); TypeInformation typeInformation = getTypeInformation(field, value); - Optional mappedValue = getConverter().convertToColumnType(value, typeInformation); + Object mappedValue = getConverter().convertToColumnType(value, typeInformation); - Predicate mappedPredicate = new Predicate(predicate.getOperator(), mappedValue.orElse(null)); + Predicate mappedPredicate = new Predicate(predicate.getOperator(), mappedValue); result.add(Criteria.of(field.getMappedKey(), mappedPredicate)); } @@ -339,11 +339,17 @@ public class QueryMapper { } @SuppressWarnings("unchecked") - TypeInformation getTypeInformation(Field field, Optional value) { + TypeInformation getTypeInformation(Field field, Object value) { - return field.getProperty().map(CassandraPersistentProperty::getTypeInformation) - .orElseGet(() -> value.map(Object::getClass).map(ClassTypeInformation::from) - .orElse((ClassTypeInformation) ClassTypeInformation.OBJECT)); + if (field.getProperty().isPresent()) { + return field.getProperty().get().getTypeInformation(); + } + + if (value != null) { + return ClassTypeInformation.from(value.getClass()); + } + + return ClassTypeInformation.OBJECT; } /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/UpdateMapper.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/UpdateMapper.java index de4a2bfb5..6ca8eb899 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/UpdateMapper.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/UpdateMapper.java @@ -120,7 +120,7 @@ public class UpdateMapper extends QueryMapper { Object rawValue = updateOp.getValue(); - Optional value = Optional.ofNullable(rawValue); + Object value = rawValue; if (updateOp instanceof SetAtKeyOp) { @@ -130,18 +130,15 @@ public class UpdateMapper extends QueryMapper { .map(PersistentProperty::getTypeInformation); Optional> keyType = typeInformation.map(TypeInformation::getActualType); - Optional> valueType = typeInformation.flatMap(TypeInformation::getMapValueType); + Optional> valueType = typeInformation.map(TypeInformation::getMapValueType); - Optional key = Optional.ofNullable(op.getKey()); - Optional val = Optional.ofNullable(op.getValue()); + Object mappedKey = keyType.map(typeInfo -> getConverter().convertToColumnType(op.getKey(), typeInfo)) + .orElseGet(() -> getConverter().convertToColumnType(op.getKey())); - Optional mappedKey = keyType.map(typeInfo -> getConverter().convertToColumnType(key, typeInfo)) - .orElseGet(() -> getConverter().convertToColumnType(key)); + Object mappedValue = valueType.map(typeInfo -> getConverter().convertToColumnType(op.getValue(), typeInfo)) + .orElseGet(() -> getConverter().convertToColumnType(op.getValue())); - Optional mappedValue = valueType.map(typeInfo -> getConverter().convertToColumnType(val, typeInfo)) - .orElseGet(() -> getConverter().convertToColumnType(val)); - - return new SetAtKeyOp(field.getMappedKey(), mappedKey.orElse(null), mappedValue.orElse(null)); + return new SetAtKeyOp(field.getMappedKey(), mappedKey, mappedValue); } TypeInformation typeInformation = getTypeInformation(field, value); @@ -150,10 +147,9 @@ public class UpdateMapper extends QueryMapper { SetAtIndexOp op = (SetAtIndexOp) updateOp; - Optional mappedValue = getConverter().convertToColumnType(Optional.ofNullable(op.getValue()), - typeInformation); + Object mappedValue = getConverter().convertToColumnType(op.getValue(), typeInformation); - return new SetAtIndexOp(field.getMappedKey(), op.getIndex(), mappedValue.orElse(null)); + return new SetAtIndexOp(field.getMappedKey(), op.getIndex(), mappedValue); } if (rawValue instanceof Collection && typeInformation.isCollectionLike()) { @@ -173,27 +169,26 @@ public class UpdateMapper extends QueryMapper { } } - Optional mappedValue = getConverter().convertToColumnType(value, typeInformation); + Object mappedValue = getConverter().convertToColumnType(value, typeInformation); - return new SetOp(field.getMappedKey(), mappedValue.orElse(null)); + return new SetOp(field.getMappedKey(), mappedValue); } private AssignmentOp getMappedUpdateOperation(Field field, RemoveOp updateOp) { - Optional value = Optional.ofNullable(updateOp.getValue()); + Object value = updateOp.getValue(); TypeInformation typeInformation = getTypeInformation(field, value); - Optional mappedValue = getConverter().convertToColumnType(value, typeInformation); + Object mappedValue = getConverter().convertToColumnType(value, typeInformation); - return new RemoveOp(field.getMappedKey(), mappedValue.orElse(null)); + return new RemoveOp(field.getMappedKey(), mappedValue); } @SuppressWarnings("unchecked") private AssignmentOp getMappedUpdateOperation(Field field, AddToOp updateOp) { - Optional> value = Optional.ofNullable(updateOp.getValue()); + Iterable value = updateOp.getValue(); TypeInformation typeInformation = getTypeInformation(field, value); - Collection mappedValue = (Collection) getConverter().convertToColumnType(value, typeInformation) - .orElse(null); + Collection mappedValue = (Collection) getConverter().convertToColumnType(value, typeInformation); if (field.getProperty().isPresent()) { @@ -221,22 +216,19 @@ public class UpdateMapper extends QueryMapper { .map(PersistentProperty::getTypeInformation); Optional> keyType = typeInformation.map(TypeInformation::getActualType); - Optional> valueType = typeInformation.flatMap(TypeInformation::getMapValueType); + Optional> valueType = typeInformation.map(TypeInformation::getMapValueType); Map result = new LinkedHashMap<>(updateOp.getValue().size(), 1); - updateOp.getValue().forEach((k, v) -> { + updateOp.getValue().forEach((key, value) -> { - Optional key = Optional.ofNullable(k); - Optional value = Optional.ofNullable(v); - - Optional mappedKey = keyType.map(typeInfo -> getConverter().convertToColumnType(key, typeInfo)) + Object mappedKey = keyType.map(typeInfo -> getConverter().convertToColumnType(key, typeInfo)) .orElseGet(() -> getConverter().convertToColumnType(key)); - Optional mappedValue = valueType.map(typeInfo -> getConverter().convertToColumnType(value, typeInfo)) + Object mappedValue = valueType.map(typeInfo -> getConverter().convertToColumnType(value, typeInfo)) .orElseGet(() -> getConverter().convertToColumnType(value)); - result.put(mappedKey.orElse(null), mappedValue.orElse(null)); + result.put(mappedKey, mappedValue); }); return new AddToMapOp(field.getMappedKey(), result); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentEntity.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentEntity.java index 641d2f2be..1c10e69f0 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentEntity.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentEntity.java @@ -17,7 +17,6 @@ package org.springframework.data.cassandra.core.mapping; import static org.springframework.data.cql.core.CqlIdentifier.*; -import java.util.Comparator; import java.util.Optional; import org.springframework.beans.BeansException; @@ -30,8 +29,8 @@ import org.springframework.data.cql.core.CqlIdentifier; import org.springframework.data.cql.support.exception.UnsupportedCassandraOperationException; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.AssociationHandler; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.model.BasicPersistentEntity; -import org.springframework.data.mapping.model.MappingException; import org.springframework.data.util.TypeInformation; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.util.Assert; @@ -52,9 +51,6 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity> PROPERTY_COMPARATOR = Optional - .of(CassandraPersistentPropertyComparator.INSTANCE); - private CassandraPersistentEntityMetadataVerifier verifier = DEFAULT_VERIFIER; private ApplicationContext context; @@ -84,18 +80,20 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity typeInformation, CassandraPersistentEntityMetadataVerifier verifier) { - super(typeInformation, PROPERTY_COMPARATOR); + super(typeInformation, CassandraPersistentPropertyComparator.INSTANCE); setVerifier(verifier); } protected CqlIdentifier determineTableName() { - Optional tableAnnotation = findAnnotation(Table.class); + Table annotation = findAnnotation(Table.class); - return tableAnnotation // - .map(annotation -> determineName(annotation.value(), annotation.forceQuote())) // - .orElseGet(this::determineDefaultName); + if (annotation != null) { + return determineName(annotation.value(), annotation.forceQuote()); + } + + return determineDefaultName(); } CqlIdentifier determineDefaultName() { @@ -132,7 +130,7 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity entity) throws MappingException { - if (entity.getType().isInterface() || !entity.findAnnotation(Table.class).isPresent()) { + if (entity.getType().isInterface() || !entity.isAnnotationPresent(Table.class)) { return; } @@ -59,7 +59,7 @@ public class BasicCassandraPersistentEntityMetadataVerifier implements Cassandra } // Parse entity properties - entity.getPersistentProperties().forEach(property -> { + entity.forEach(property -> { if (property.isIdProperty()) { idProperties.add(property); } else if (property.isClusterKeyColumn()) { diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentProperty.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentProperty.java index 25c7b857e..0e7f953df 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentProperty.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentProperty.java @@ -33,8 +33,8 @@ import org.springframework.data.cql.core.CqlIdentifier; import org.springframework.data.cql.core.Ordering; import org.springframework.data.cql.core.PrimaryKeyType; import org.springframework.data.mapping.Association; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; -import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.TypeInformation; @@ -140,8 +140,15 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP * @see org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty#getPrimaryKeyOrdering() */ @Override - public Optional getPrimaryKeyOrdering() { - return findAnnotation(PrimaryKeyColumn.class).map(PrimaryKeyColumn::ordering); + public Ordering getPrimaryKeyOrdering() { + + PrimaryKeyColumn annotation = findAnnotation(PrimaryKeyColumn.class); + + if (annotation != null) { + return annotation.ordering(); + } + + return null; } /* (non-Javadoc) @@ -163,10 +170,10 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP private DataType findDataType() { - Optional cassandraType = findAnnotation(CassandraType.class); + CassandraType cassandraType = findAnnotation(CassandraType.class); - if (cassandraType.isPresent()) { - return getDataTypeFor(cassandraType.get()); + if (cassandraType != null) { + return getDataTypeFor(cassandraType); } if (isMap()) { @@ -298,8 +305,8 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP @Override public boolean isPartitionKeyColumn() { - return findAnnotation(PrimaryKeyColumn.class) - .filter(primaryKeyColumn -> PrimaryKeyType.PARTITIONED.equals(primaryKeyColumn.type())).isPresent(); + PrimaryKeyColumn annotation = findAnnotation(PrimaryKeyColumn.class); + return annotation != null && PrimaryKeyType.PARTITIONED.equals(annotation.type()); } /* (non-Javadoc) @@ -308,8 +315,8 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP @Override public boolean isClusterKeyColumn() { - return findAnnotation(PrimaryKeyColumn.class) - .filter(primaryKeyColumn -> PrimaryKeyType.CLUSTERED.equals(primaryKeyColumn.type())).isPresent(); + PrimaryKeyColumn annotation = findAnnotation(PrimaryKeyColumn.class); + return annotation != null && PrimaryKeyType.CLUSTERED.equals(annotation.type()); } private CqlIdentifier determineColumnName() { @@ -319,23 +326,33 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP } String defaultName = getName(); // TODO: replace with naming strategy class - String overriddenName; - boolean forceQuote; + String overriddenName = null; + boolean forceQuote = false; if (isIdProperty()) { // then the id is of a simple type (since it's not a composite primary key) - Optional optionalPrimaryKey = findAnnotation(PrimaryKey.class); - overriddenName = optionalPrimaryKey.map(PrimaryKey::value).orElse(""); - forceQuote = optionalPrimaryKey.map(PrimaryKey::forceQuote).orElse(false); + PrimaryKey primaryKey = findAnnotation(PrimaryKey.class); + + if (primaryKey != null) { + overriddenName = primaryKey.value(); + forceQuote = primaryKey.forceQuote(); + } } else if (isPrimaryKeyColumn()) { // then it's a simple type - Optional optionalPrimaryKey = findAnnotation(PrimaryKeyColumn.class); - overriddenName = optionalPrimaryKey.map(PrimaryKeyColumn::value).orElse(""); - forceQuote = optionalPrimaryKey.map(PrimaryKeyColumn::forceQuote).orElse(false); + PrimaryKeyColumn primaryKeyColumn = findAnnotation(PrimaryKeyColumn.class); + + if (primaryKeyColumn != null) { + overriddenName = primaryKeyColumn.value(); + forceQuote = primaryKeyColumn.forceQuote(); + } } else { // then it's a vanilla column with the assumption that it's mapped to a single column - Optional optionalColumn = findAnnotation(Column.class); - overriddenName = optionalColumn.map(Column::value).orElse(""); - forceQuote = optionalColumn.map(Column::forceQuote).orElse(false); + + Column column = findAnnotation(Column.class); + + if (column != null) { + overriddenName = column.value(); + forceQuote = column.forceQuote(); + } } return createColumnName(defaultName, overriddenName, forceQuote); @@ -386,8 +403,8 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP * @see org.springframework.data.mapping.model.AbstractPersistentProperty#getAssociation() */ @Override - public Optional> getAssociation() { - return Optional.empty(); + public Association getAssociation() { + return null; } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContext.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContext.java index 831f1a157..0b14b2e12 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContext.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContext.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.stream.StreamSupport; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; @@ -40,11 +41,10 @@ import org.springframework.data.convert.CustomConversions; import org.springframework.data.cql.core.CqlIdentifier; import org.springframework.data.cql.core.keyspace.CreateTableSpecification; import org.springframework.data.cql.core.keyspace.CreateUserTypeSpecification; -import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.context.AbstractMappingContext; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.Optionals; @@ -258,8 +258,8 @@ public class CassandraMappingContext entities.add(entity); - if (!entity.isUserDefinedType()) { - entity.findAnnotation(Table.class).ifPresent(table -> tableEntities.add(entity)); + if (!entity.isUserDefinedType() && entity.isAnnotationPresent(Table.class)) { + tableEntities.add(entity); } }); @@ -347,10 +347,8 @@ public class CassandraMappingContext private boolean hasReferencedUserType(CqlIdentifier identifier) { return getPersistentEntities().stream() // - .flatMap(PersistentEntity::getPersistentProperties) // - .map(it -> it.findAnnotation(CassandraType.class)) // - .filter(Optional::isPresent) // - .flatMap(Optionals::toStream) // + .flatMap(entity -> StreamSupport.stream(entity.spliterator(), false)) // + .flatMap(it -> Optionals.toStream(Optional.ofNullable(it.findAnnotation(CassandraType.class)))) // .map(CassandraType::userTypeName) // .filter(StringUtils::hasText) // .map(CqlIdentifier::cqlId) // @@ -372,11 +370,15 @@ public class CassandraMappingContext final CreateTableSpecification specification = createTable().name(entity.getTableName()); - entity.getPersistentProperties().filter(CassandraPersistentProperty::isCompositePrimaryKey).forEach(property -> { + for (CassandraPersistentProperty property : entity) { + + if (!property.isCompositePrimaryKey()) { + continue; + } CassandraPersistentEntity primaryKeyEntity = getRequiredPersistentEntity(property.getRawType()); - primaryKeyEntity.getPersistentProperties().forEach(primaryKeyProperty -> { + for (CassandraPersistentProperty primaryKeyProperty : primaryKeyEntity) { if (primaryKeyProperty.isPartitionKeyColumn()) { specification.partitionKeyColumn(primaryKeyProperty.getColumnName(), getDataType(primaryKeyProperty)); @@ -384,12 +386,15 @@ public class CassandraMappingContext specification.clusteredKeyColumn(primaryKeyProperty.getColumnName(), getDataType(primaryKeyProperty), primaryKeyProperty.getPrimaryKeyOrdering()); } + } + } - }); + for (CassandraPersistentProperty property : entity) { - }); + if (property.isCompositePrimaryKey()) { + continue; + } - entity.getPersistentProperties().filter((property) -> !property.isCompositePrimaryKey()).forEach(property -> { if (property.isIdProperty() || property.isPartitionKeyColumn()) { specification.partitionKeyColumn(property.getColumnName(), UserTypeUtil.potentiallyFreeze(getDataType(property))); @@ -399,7 +404,7 @@ public class CassandraMappingContext } else { specification.column(property.getColumnName(), UserTypeUtil.potentiallyFreeze(getDataType(property))); } - }); + } if (specification.getPartitionKeyColumns().isEmpty()) { throw new MappingException(String.format("No partition key columns found in entity [%s]", entity.getType())); @@ -451,18 +456,18 @@ public class CassandraMappingContext private DataType getDataTypeWithUserTypeFactory(CassandraPersistentProperty property, DataTypeProvider dataTypeProvider) { - if (property.findAnnotation(CassandraType.class).isPresent()) { + if (property.isAnnotationPresent(CassandraType.class)) { return property.getDataType(); } - Optional> persistentEntity = getPersistentEntity(property.getActualType()); + BasicCassandraPersistentEntity persistentEntity = getPersistentEntity(property.getActualType()); - if (persistentEntity.filter(CassandraPersistentEntity::isUserDefinedType).isPresent()) { + if (persistentEntity != null && persistentEntity.isUserDefinedType()) { - Optional dataType = persistentEntity.map(it -> getUserDataType(property, dataTypeProvider, it)); + DataType dataType = getUserDataType(property, dataTypeProvider, persistentEntity); - if (dataType.isPresent()) { - return dataType.get(); + if (dataType != null) { + return dataType; } } @@ -488,8 +493,8 @@ public class CassandraMappingContext if (property.isMapLike()) { - Class keyType = property.getComponentType().get(); - Class valueType = property.getMapValueType().get(); + Class keyType = property.getComponentType(); + Class valueType = property.getMapValueType(); return DataType.map(getDataType(keyType, dataTypeProvider), getDataType(valueType, dataTypeProvider)); } @@ -500,10 +505,9 @@ public class CassandraMappingContext private DataType getDataType(Class type, DataTypeProvider dataTypeProvider) { - return getPersistentEntity(type) // - .filter(CassandraPersistentEntity::isUserDefinedType) // - .map(dataTypeProvider::getDataType) // - .orElseGet(() -> getDataType(type)); + BasicCassandraPersistentEntity entity = getPersistentEntity(type); + + return entity != null && entity.isUserDefinedType() ? dataTypeProvider.getDataType(entity) : getDataType(type); } private DataType getUserDataType(CassandraPersistentProperty property, DataTypeProvider dataTypeProvider, diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentEntityMetadataVerifier.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentEntityMetadataVerifier.java index bef3e249a..c326eaaa0 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentEntityMetadataVerifier.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentEntityMetadataVerifier.java @@ -15,12 +15,13 @@ */ package org.springframework.data.cassandra.core.mapping; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; /** * Interface for Cassandra Persistent Entity Mapping Verification. * * @author David Webb + * @author Mark Paluch */ public interface CassandraPersistentEntityMetadataVerifier { diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentProperty.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentProperty.java index f5fa734b9..ceb26efc4 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentProperty.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentProperty.java @@ -15,8 +15,6 @@ */ package org.springframework.data.cassandra.core.mapping; -import java.util.Optional; - import org.springframework.context.ApplicationContextAware; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.cql.core.CqlIdentifier; @@ -46,7 +44,7 @@ public interface CassandraPersistentProperty * The ordering (ascending or descending) for the column. Valid only for primary key columns; returns null for * non-primary key columns. */ - Optional getPrimaryKeyOrdering(); + Ordering getPrimaryKeyOrdering(); /** * The column's data type. Not valid for a composite primary key. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentPropertyComparator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentPropertyComparator.java index 1b16acf72..9b148f318 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentPropertyComparator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraPersistentPropertyComparator.java @@ -16,7 +16,6 @@ package org.springframework.data.cassandra.core.mapping; import java.util.Comparator; -import java.util.Optional; import org.springframework.data.cql.core.CqlIdentifier; @@ -79,14 +78,14 @@ public enum CassandraPersistentPropertyComparator implements Comparator optionalLeftAnnotation = left.findAnnotation(PrimaryKeyColumn.class); - Optional optionaRightAnnotation = right.findAnnotation(PrimaryKeyColumn.class); + PrimaryKeyColumn leftAnnotation = left.findAnnotation(PrimaryKeyColumn.class); + PrimaryKeyColumn rightAnnotation = right.findAnnotation(PrimaryKeyColumn.class); - return optionalLeftAnnotation.map(leftAnnotation -> { - return optionaRightAnnotation.map(rightAnnotation -> CassandraPrimaryKeyColumnAnnotationComparator.INSTANCE - .compare(leftAnnotation, rightAnnotation)).orElse(0); + if (leftAnnotation == null || rightAnnotation == null) { + return 0; + } - }).orElse(0); + return CassandraPrimaryKeyColumnAnnotationComparator.INSTANCE.compare(leftAnnotation, rightAnnotation); } boolean leftIsKey = leftIsCompositePrimaryKey || leftIsPrimaryKey; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraUserTypePersistentEntity.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraUserTypePersistentEntity.java index 32133c6cf..bd2c499db 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraUserTypePersistentEntity.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CassandraUserTypePersistentEntity.java @@ -16,7 +16,7 @@ package org.springframework.data.cassandra.core.mapping; import org.springframework.data.cql.core.CqlIdentifier; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; @@ -61,9 +61,13 @@ public class CassandraUserTypePersistentEntity extends BasicCassandraPersiste @Override protected CqlIdentifier determineTableName() { - return findAnnotation(UserDefinedType.class) // - .map(userDefinedType -> determineName(userDefinedType.value(), userDefinedType.forceQuote())) // - .orElseGet(super::determineDefaultName); + UserDefinedType annotation = findAnnotation(UserDefinedType.class); + + if (annotation != null) { + return determineName(annotation.value(), annotation.forceQuote()); + } + + return super.determineTableName(); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CompositeCassandraPersistentEntityMetadataVerifier.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CompositeCassandraPersistentEntityMetadataVerifier.java index 9dfa3d6ab..06cc22378 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CompositeCassandraPersistentEntityMetadataVerifier.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CompositeCassandraPersistentEntityMetadataVerifier.java @@ -18,7 +18,7 @@ package org.springframework.data.cassandra.core.mapping; import java.util.Arrays; import java.util.Collection; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.util.Assert; /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/PrimaryKeyClassEntityMetadataVerifier.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/PrimaryKeyClassEntityMetadataVerifier.java index bd3e34684..01aeb6869 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/PrimaryKeyClassEntityMetadataVerifier.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/PrimaryKeyClassEntityMetadataVerifier.java @@ -19,7 +19,7 @@ import java.util.ArrayList; import java.util.List; import org.springframework.data.annotation.Id; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; /** * {@link CassandraPersistentEntityMetadataVerifier} for {@link PrimaryKeyClass} entities. Ensures a valid mapping for @@ -52,7 +52,7 @@ public class PrimaryKeyClassEntityMetadataVerifier implements CassandraPersisten Class entityType = entity.getType(); // Ensure entity is not both a @Table(@Persistent) and a @PrimaryKey - if (entity.findAnnotation(Table.class).isPresent()) { + if (entity.isAnnotationPresent(Table.class)) { exceptions.add(new MappingException(String.format("Entity cannot be of type @%s and @%s", Table.class.getSimpleName(), PrimaryKeyClass.class.getSimpleName()))); } @@ -63,7 +63,7 @@ public class PrimaryKeyClassEntityMetadataVerifier implements CassandraPersisten new MappingException(String.format("@%s must only extend Object", PrimaryKeyClass.class.getSimpleName()))); } - entity.getPersistentProperties().forEach(property -> { + entity.forEach(property -> { if (property.isCompositePrimaryKey()) { compositePrimaryKeys.add(property); } else if (property.isIdProperty()) { diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/VerifierMappingExceptions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/VerifierMappingExceptions.java index e88d7ef57..3638eef22 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/VerifierMappingExceptions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/VerifierMappingExceptions.java @@ -20,7 +20,7 @@ import java.util.Collections; import java.util.LinkedList; import java.util.stream.Collectors; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.util.Assert; /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java index f7aabe8d8..c880489a0 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java @@ -103,12 +103,11 @@ public class CassandraQueryMethod extends QueryMethod { } else { - Optional> optionalReturnedEntity = mappingContext - .getPersistentEntity(returnedObjectType).map(CassandraPersistentEntity.class::cast); + CassandraPersistentEntity entity = mappingContext.getPersistentEntity(returnedObjectType); CassandraPersistentEntity managedEntity = mappingContext.getRequiredPersistentEntity(domainClass); - CassandraPersistentEntity returnedEntity = optionalReturnedEntity.filter(e -> !e.getType().isInterface()) - .orElse(managedEntity); + CassandraPersistentEntity returnedEntity = entity != null && entity.getType().isInterface() ? entity + : managedEntity; // TODO collectionEntity? CassandraPersistentEntity collectionEntity = domainClass.isAssignableFrom(returnedObjectType) 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 ea116c34f..0a5b5ae5b 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 @@ -26,7 +26,6 @@ import org.springframework.data.cassandra.core.mapping.CassandraSimpleTypeHolder import org.springframework.data.cassandra.core.mapping.CassandraType; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; @@ -85,7 +84,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { */ @Override public Object getBindableValue(int index) { - return potentiallyConvert(index, Optional.ofNullable(delegate.getBindableValue(index))); + return potentiallyConvert(index, delegate.getBindableValue(index)); } /* (non-Javadoc) @@ -139,24 +138,24 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { } @SuppressWarnings("unchecked") - private Object potentiallyConvert(int index, Optional bindableValue) { + private Object potentiallyConvert(int index, Object bindableValue) { - return bindableValue - .flatMap(v -> converter.convertToColumnType(bindableValue, findTypeInformation(index, v, Optional.empty()))) - .orElse(null); + if (bindableValue == null) { + return null; + } + + return converter.convertToColumnType(bindableValue, findTypeInformation(index, bindableValue, null)); } @SuppressWarnings("unchecked") - private Object potentiallyConvert(int index, Optional bindableValue, CassandraPersistentProperty property) { + private Object potentiallyConvert(int index, Object bindableValue, CassandraPersistentProperty property) { - return bindableValue - .flatMap( - v -> converter.convertToColumnType(bindableValue, findTypeInformation(index, v, Optional.of(property)))) - .orElse(null); + return (bindableValue == null ? null + : converter.convertToColumnType(bindableValue, findTypeInformation(index, bindableValue, property))); } private TypeInformation findTypeInformation(int index, Object bindableValue, - Optional property) { + CassandraPersistentProperty property) { if (delegate.findCassandraType(index) != null) { TypeCodec typeCodec = CodecRegistry.DEFAULT_INSTANCE.codecFor(getDataType(index, property)); @@ -168,8 +167,11 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { return ClassTypeInformation.from(typeCodec.getJavaType().getRawType()); } - return property.map(PersistentProperty::getTypeInformation) - .orElseGet(() -> (TypeInformation) ClassTypeInformation.from(bindableValue.getClass())); + if (property == null) { + return ClassTypeInformation.from(bindableValue.getClass()); + } + + return property.getTypeInformation(); } /** @@ -180,7 +182,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { * @param property {@link CassandraPersistentProperty}. * @return the {@link DataType} */ - DataType getDataType(int index, Optional optionalProperty) { + DataType getDataType(int index, CassandraPersistentProperty property) { CassandraType cassandraType = delegate.findCassandraType(index); @@ -191,9 +193,11 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { CassandraMappingContext mappingContext = converter.getMappingContext(); TypeInformation typeInformation = ClassTypeInformation.from(getParameterType(index)); - return optionalProperty.map(property -> getDataType(mappingContext, typeInformation, property)) - .orElseGet(() -> mappingContext.getDataType(typeInformation.getType())); + if (property == null) { + return mappingContext.getDataType(typeInformation.getType()); + } + return getDataType(mappingContext, typeInformation, property); } private DataType getDataType(CassandraMappingContext mappingContext, TypeInformation typeInformation, @@ -265,7 +269,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { * @see java.util.Iterator#next() */ public Object next() { - return potentiallyConvert(index++, Optional.ofNullable(delegate.next())); + return potentiallyConvert(index++, delegate.next()); } /* @@ -281,7 +285,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { */ @Override public Object nextConverted(CassandraPersistentProperty property) { - return potentiallyConvert(index++, Optional.ofNullable(delegate.next()), property); + return potentiallyConvert(index++, delegate.next(), property); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/DtoInstantiatingConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/DtoInstantiatingConverter.java index 55ce32a53..75da7ae54 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/DtoInstantiatingConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/DtoInstantiatingConverter.java @@ -15,8 +15,6 @@ */ package org.springframework.data.cassandra.repository.query; -import java.util.Optional; - import org.springframework.core.convert.converter.Converter; import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity; import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; @@ -43,7 +41,7 @@ class DtoInstantiatingConverter implements Converter { private final MappingContext, ? extends PersistentProperty> context; - private final Optional instantiator; + private final EntityInstantiator instantiator; /** * Create a new {@link Converter} to instantiate DTOs. @@ -62,8 +60,7 @@ class DtoInstantiatingConverter implements Converter { this.targetType = dtoType; this.context = context; - - this.instantiator = context.getPersistentEntity(dtoType).map(instantiator::getInstantiatorFor); + this.instantiator = instantiator.getInstantiatorFor(context.getRequiredPersistentEntity(dtoType)); } /* @@ -81,29 +78,28 @@ class DtoInstantiatingConverter implements Converter { PersistentPropertyAccessor sourceAccessor = sourceEntity.getPropertyAccessor(source); PersistentEntity targetEntity = context.getRequiredPersistentEntity(targetType); - EntityInstantiator instantiator = this.instantiator.orElseThrow( - () -> new IllegalStateException(String.format("No EntityInstantiator for [%s] available", targetType))); - @SuppressWarnings({ "rawtypes", "unchecked" }) Object dto = instantiator.createInstance(targetEntity, new ParameterValueProvider() { @Override - public Optional getParameterValue(Parameter parameter) { + public Object getParameterValue(Parameter parameter) { // TODO: Fix generics - return parameter.getName() - .flatMap(name -> sourceAccessor.getProperty(sourceEntity.getRequiredPersistentProperty((String) name))); + if (parameter != null) { + return sourceAccessor.getProperty(sourceEntity.getRequiredPersistentProperty(parameter.getName())); + } + + return null; } }); final PersistentPropertyAccessor targetAccessor = targetEntity.getPropertyAccessor(dto); - Optional>> optionalConstructor = targetEntity - .getPersistenceConstructor(); + PreferredConstructor> constructor = targetEntity.getPersistenceConstructor(); targetEntity.doWithProperties((SimplePropertyHandler) property -> { - if (!optionalConstructor.filter(c -> c.isConstructorParameter(property)).isPresent()) { + if (!constructor.isConstructorParameter(property)) { return; } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceException.java index 3aaa765d3..d5b5555ab 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceException.java @@ -17,7 +17,7 @@ package org.springframework.data.cassandra.repository.support; import java.lang.reflect.Method; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; /** * Exception thrown on incorrect mapping of an Id interface. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceExceptions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceExceptions.java index d9ea5829a..1c1b5b3eb 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceExceptions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceExceptions.java @@ -20,7 +20,7 @@ import java.util.Collections; import java.util.LinkedList; import java.util.stream.Collectors; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.util.Assert; /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceValidator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceValidator.java index 726ac1632..50d432c50 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceValidator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/IdInterfaceValidator.java @@ -20,7 +20,7 @@ import java.util.ArrayList; import java.util.List; import org.springframework.data.cassandra.repository.MapId; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; /** * @author Matthew T. Adams diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/MappingCassandraEntityInformation.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/MappingCassandraEntityInformation.java index c100c8961..b4d164e6d 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/MappingCassandraEntityInformation.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/MappingCassandraEntityInformation.java @@ -15,8 +15,6 @@ */ package org.springframework.data.cassandra.repository.support; -import java.util.Optional; - import org.springframework.data.cassandra.core.convert.CassandraConverter; import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity; import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; @@ -59,15 +57,16 @@ public class MappingCassandraEntityInformation extends AbstractEntityInfo */ @SuppressWarnings("unchecked") @Override - public Optional getId(T entity) { + public ID getId(T entity) { Assert.notNull(entity, "Entity must not be null"); - Optional idProperty = entityMetadata.getIdProperty(); + CassandraPersistentProperty idProperty = entityMetadata.getIdProperty(); - // FIXME: Cast - return idProperty.map(p -> entityMetadata.getIdentifierAccessor(entity).getIdentifier()) - .orElseGet(() -> Optional.ofNullable(converter.getId(entity, entityMetadata))).map(o -> (ID) o); + if (idProperty != null) { + return (ID) entityMetadata.getIdentifierAccessor(entity).getIdentifier(); + } + return (ID) converter.getId(entity, entityMetadata); } /* (non-Javadoc) @@ -76,7 +75,12 @@ public class MappingCassandraEntityInformation extends AbstractEntityInfo @SuppressWarnings("unchecked") @Override public Class getIdType() { - return entityMetadata.getIdProperty().map(p -> (Class) p.getType()).orElse((Class) MapId.class); + + if (entityMetadata.getIdProperty() != null) { + return (Class) entityMetadata.getIdProperty().getType(); + } + + return (Class) MapId.class; } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepository.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepository.java index 0fb389b55..5563ba6fd 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepository.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepository.java @@ -219,8 +219,7 @@ public class SimpleCassandraRepository implements CassandraRepository new IllegalArgumentException(String.format("Cannot obtain Id from [%s]", entity)))); + deleteById(entityInformation.getRequiredId(entity)); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentEntityMetadataVerifierUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentEntityMetadataVerifierUnitTests.java index 7aaa48d8e..67d20eea7 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentEntityMetadataVerifierUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentEntityMetadataVerifierUnitTests.java @@ -22,7 +22,7 @@ import org.junit.Test; import org.springframework.data.annotation.Id; import org.springframework.data.cql.core.Ordering; import org.springframework.data.cql.core.PrimaryKeyType; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; /** * Unit tests for {@link org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentEntityMetadataVerifier} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentPropertyUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentPropertyUnitTests.java index 4c07d6125..5761f4a4e 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentPropertyUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentPropertyUnitTests.java @@ -92,7 +92,7 @@ public class BasicCassandraPersistentPropertyUnitTests { "column"); assertThat(persistentProperty.getDataType().getName()).isEqualTo(Name.COUNTER); - assertThat(persistentProperty.findAnnotation(CassandraType.class)).isPresent(); + assertThat(persistentProperty.findAnnotation(CassandraType.class)).isNotNull(); } private CassandraPersistentProperty getPropertyFor(Class type, String fieldName) { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContextUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContextUnitTests.java index acce95782..10e0f0c04 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContextUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CassandraMappingContextUnitTests.java @@ -23,7 +23,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Optional; import org.junit.Before; import org.junit.Test; @@ -37,7 +36,7 @@ import org.springframework.data.cql.core.Ordering; import org.springframework.data.cql.core.PrimaryKeyType; import org.springframework.data.cql.core.keyspace.ColumnSpecification; import org.springframework.data.cql.core.keyspace.CreateTableSpecification; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.util.ClassTypeInformation; import com.datastax.driver.core.DataType; @@ -88,9 +87,9 @@ public class CassandraMappingContextUnitTests { CassandraPersistentEntity persistentEntity = mappingContext .getRequiredPersistentEntity(PrimaryKeyOnProperty.class); - Optional idProperty = persistentEntity.getIdProperty(); + CassandraPersistentProperty idProperty = persistentEntity.getIdProperty(); - assertThat(idProperty).hasValueSatisfying(actual -> { + assertThat(idProperty).satisfies(actual -> { assertThat(actual.getColumnName().toCql()).isEqualTo("foo"); }); @@ -168,9 +167,7 @@ public class CassandraMappingContextUnitTests { .getRequiredPersistentEntity(CompositePrimaryKeyClassWithProperties.class); assertThat(persistentEntity.isCompositePrimaryKey()).isFalse(); - assertThat( - persistentEntity.getPersistentProperty("key").map(CassandraPersistentProperty::isCompositePrimaryKey).get()) - .isTrue(); + assertThat(persistentEntity.getPersistentProperty("key").isCompositePrimaryKey()).isTrue(); assertThat(primaryKeyClass.isCompositePrimaryKey()).isTrue(); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java index 80fc713dd..922aac958 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java @@ -23,7 +23,7 @@ import org.junit.Test; import org.springframework.data.annotation.Id; import org.springframework.data.cql.core.Ordering; import org.springframework.data.cql.core.PrimaryKeyType; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; /** * Unit tests for {@link CompositeCassandraPersistentEntityMetadataVerifier}. diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/PrimaryKeyClassEntityMetadataVerifierUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/PrimaryKeyClassEntityMetadataVerifierUnitTests.java index a61909031..6c7b05764 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/PrimaryKeyClassEntityMetadataVerifierUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/mapping/PrimaryKeyClassEntityMetadataVerifierUnitTests.java @@ -23,7 +23,7 @@ import org.junit.Test; import org.springframework.data.annotation.Id; import org.springframework.data.cql.core.Ordering; import org.springframework.data.cql.core.PrimaryKeyType; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; /** * Unit tests for {@link PrimaryKeyClassEntityMetadataVerifier}. 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 515ac016d..8cff5135e 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 @@ -22,7 +22,6 @@ import java.time.LocalDate; import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Optional; import org.junit.Before; import org.junit.Test; @@ -30,7 +29,6 @@ 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.CassandraMappingContext; import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty; import org.springframework.data.cassandra.core.mapping.CassandraType; import org.springframework.data.cassandra.repository.query.ConvertingParameterAccessor.PotentiallyConvertingIterator; @@ -57,7 +55,7 @@ public class ConvertingParameterAccessorUnitTests { @Before public void setUp() { - this.converter = new MappingCassandraConverter(new CassandraMappingContext()); + this.converter = new MappingCassandraConverter(); this.converter.afterPropertiesSet(); this.convertingParameterAccessor = new ConvertingParameterAccessor(converter, mockParameterAccessor); } @@ -135,9 +133,9 @@ public class ConvertingParameterAccessorUnitTests { public void shouldProvideTypeBasedOnPropertyType() { when(mockProperty.getDataType()).thenReturn(DataType.varchar()); - when(mockProperty.findAnnotation(CassandraType.class)).thenReturn(Optional.of(mock(CassandraType.class))); + when(mockProperty.isAnnotationPresent(CassandraType.class)).thenReturn(true); when(mockParameterAccessor.getParameterType(0)).thenReturn((Class) String.class); - assertThat(convertingParameterAccessor.getDataType(0, Optional.of(mockProperty))).isEqualTo(DataType.varchar()); + assertThat(convertingParameterAccessor.getDataType(0, mockProperty)).isEqualTo(DataType.varchar()); } }