From 697f5ad7c6effda9067ab7f1d53d1b8604696cad Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 26 Jun 2017 16:42:36 +0200 Subject: [PATCH] DATAMONGO-1730 - Adapt to API changes in mapping subsystem. --- .../data/mongodb/core/MongoTemplate.java | 184 +++++------ .../mongodb/core/ReactiveMongoTemplate.java | 133 ++++---- .../mongodb/core/convert/DbRefResolver.java | 15 +- .../convert/DefaultDbRefProxyHandler.java | 8 +- .../core/convert/DefaultDbRefResolver.java | 39 ++- .../convert/DefaultDbRefResolverCallback.java | 11 +- .../core/convert/DefaultMongoTypeMapper.java | 24 +- .../core/convert/DocumentAccessor.java | 28 +- .../core/convert/MappingMongoConverter.java | 297 +++++++++++------- .../core/convert/MongoExampleMapper.java | 24 +- .../data/mongodb/core/convert/ObjectPath.java | 38 +-- .../mongodb/core/convert/QueryMapper.java | 67 ++-- .../mongodb/core/convert/ValueResolver.java | 8 +- .../MongoPersistentEntityIndexCreator.java | 2 +- .../MongoPersistentEntityIndexResolver.java | 61 ++-- .../mapping/BasicMongoPersistentEntity.java | 86 ++--- .../mapping/BasicMongoPersistentProperty.java | 31 +- .../mongodb/core/mapping/EntityHandler.java | 37 --- .../query/DtoInstantiatingConverter.java | 17 +- .../repository/query/MongoParameters.java | 24 +- .../repository/query/MongoQueryCreator.java | 24 +- .../repository/query/MongoQueryExecution.java | 22 +- .../repository/query/MongoQueryMethod.java | 10 +- .../query/ReactiveMongoQueryExecution.java | 8 +- .../query/ReactiveMongoQueryMethod.java | 16 +- .../MappingMongoEntityInformation.java | 17 +- .../PersistableMongoEntityInformation.java | 6 +- .../support/SpringDataMongodbSerializer.java | 18 +- ...DefaultBulkOperationsIntegrationTests.java | 4 +- .../core/DefaultBulkOperationsUnitTests.java | 6 +- .../core/MongoOperationsUnitTests.java | 3 +- .../data/mongodb/core/MongoTemplateTests.java | 6 +- .../core/ReactiveMongoTemplateTests.java | 12 +- .../core/aggregation/AggregationTests.java | 2 +- ...ExpressionTransformerIntegrationTests.java | 2 +- ...dAggregationOperationContextUnitTests.java | 2 +- .../DbRefMappingMongoConverterUnitTests.java | 4 +- .../DefaultMongoTypeMapperUnitTests.java | 9 +- .../MappingMongoConverterUnitTests.java | 2 +- .../core/convert/QueryMapperUnitTests.java | 3 +- .../core/convert/UpdateMapperUnitTests.java | 2 +- .../BasicMongoPersistentEntityUnitTests.java | 2 +- ...BasicMongoPersistentPropertyUnitTests.java | 2 +- .../mapping/MongoMappingContextUnitTests.java | 10 +- .../performance/ReactivePerformanceTests.java | 17 +- .../query/AbstractMongoQueryUnitTests.java | 5 +- .../support/SimpleMongoRepositoryTests.java | 5 +- 47 files changed, 683 insertions(+), 670 deletions(-) delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/EntityHandler.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index d22578da0..fca57dd5d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -17,22 +17,10 @@ package org.springframework.data.mongodb.core; import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.SerializationUtils.*; -import static org.springframework.data.util.Optionals.*; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.Scanner; -import java.util.Set; import java.util.concurrent.TimeUnit; import org.bson.Document; @@ -60,11 +48,10 @@ import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResult; import org.springframework.data.geo.GeoResults; import org.springframework.data.geo.Metric; -import org.springframework.data.mapping.PersistentEntity; +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.MappingException; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.BulkOperations.BulkMode; import org.springframework.data.mongodb.core.DefaultBulkOperations.BulkOperationContext; @@ -558,8 +545,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, Assert.notNull(mode, "BulkMode must not be null!"); Assert.hasText(collectionName, "Collection name must not be null or empty!"); - DefaultBulkOperations operations = new DefaultBulkOperations(this, collectionName, - new BulkOperationContext(mode, getPersistentEntity(entityType), queryMapper, updateMapper)); + DefaultBulkOperations operations = new DefaultBulkOperations(this, collectionName, new BulkOperationContext(mode, + Optional.ofNullable(getPersistentEntity(entityType)), queryMapper, updateMapper)); operations.setExceptionTranslator(exceptionTranslator); operations.setDefaultWriteConcern(writeConcern); @@ -640,9 +627,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, public T findById(Object id, Class entityClass, String collectionName) { - String idKey = mappingContext.getPersistentEntity(entityClass)// - .flatMap(it -> it.getIdProperty())// - .map(it -> it.getName()).orElse(ID_FIELD); + MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(entityClass); + String idKey = ID_FIELD; + if (persistentEntity != null) { + if (persistentEntity.getIdProperty() != null) { + idKey = persistentEntity.getIdProperty().getName(); + } + } return doFindOne(collectionName, new Document(idKey, id), null, entityClass); } @@ -775,11 +766,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, Assert.hasText(collectionName, "Collection name must not be null or empty!"); - final Document document = query == null ? null + Document document = query == null ? null : queryMapper.getMappedObject(query.getQueryObject(), - Optional.ofNullable(entityClass).flatMap(it -> mappingContext.getPersistentEntity(entityClass))); + Optional.ofNullable(entityClass).map(it -> mappingContext.getPersistentEntity(entityClass))); - return execute(collectionName, (CollectionCallback) collection -> collection.count(document)); + return execute(collectionName, collection -> collection.count(document)); } /* @@ -896,13 +887,16 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, private void initializeVersionProperty(Object entity) { - Optional> persistentEntity = getPersistentEntity(entity.getClass()); + MongoPersistentEntity persistentEntity = getPersistentEntity(entity.getClass()); - ifAllPresent(persistentEntity, persistentEntity.flatMap(PersistentEntity::getVersionProperty), (l, r) -> { - ConvertingPropertyAccessor accessor = new ConvertingPropertyAccessor(l.getPropertyAccessor(entity), + if (persistentEntity != null && persistentEntity.hasVersionProperty()) { + + MongoPersistentProperty versionProperty = persistentEntity.getRequiredVersionProperty(); + + ConvertingPropertyAccessor accessor = new ConvertingPropertyAccessor(persistentEntity.getPropertyAccessor(entity), mongoConverter.getConversionService()); - accessor.setProperty(r, Optional.of(0)); - }); + accessor.setProperty(versionProperty, 0); + } } public void insert(Collection batchToSave, Class entityClass) { @@ -984,12 +978,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, Assert.notNull(objectToSave, "Object to save must not be null!"); Assert.hasText(collectionName, "Collection name must not be null or empty!"); - Optional> entity = getPersistentEntity(objectToSave.getClass()); - Optional versionProperty = entity.flatMap(PersistentEntity::getVersionProperty); + MongoPersistentEntity entity = getPersistentEntity(objectToSave.getClass()); - mapIfAllPresent(entity, versionProperty, // - (l, r) -> doSaveVersioned(objectToSave, l, collectionName))// - .orElseGet(() -> doSave(collectionName, objectToSave, this.mongoConverter)); + if (entity != null && entity.hasVersionProperty()) { + doSaveVersioned(objectToSave, entity, collectionName); + return; + } + + doSave(collectionName, objectToSave, this.mongoConverter); } private T doSaveVersioned(T objectToSave, MongoPersistentEntity entity, String collectionName) { @@ -997,13 +993,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, ConvertingPropertyAccessor convertingAccessor = new ConvertingPropertyAccessor( entity.getPropertyAccessor(objectToSave), mongoConverter.getConversionService()); - Optional versionProperty = entity.getVersionProperty(); - Optional versionNumber = versionProperty.flatMap(it -> convertingAccessor.getProperty(it, Number.class)); + MongoPersistentProperty property = entity.getRequiredVersionProperty(); + Number number = convertingAccessor.getProperty(property, Number.class); - return mapIfAllPresent(versionProperty, versionNumber, (property, number) -> { + if (number != null) { // Bump version number - convertingAccessor.setProperty(property, Optional.of(number.longValue() + 1)); + convertingAccessor.setProperty(property, number.longValue() + 1); maybeEmitEvent(new BeforeConvertEvent(objectToSave, collectionName)); assertUpdateableIdIfNotSet(objectToSave); @@ -1025,16 +1021,16 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, if (result.getModifiedCount() == 0) { throw new OptimisticLockingFailureException( String.format("Cannot save entity %s with version %s to collection %s. Has it been modified meanwhile?", id, - versionNumber, collectionName)); + number, collectionName)); } maybeEmitEvent(new AfterSaveEvent(objectToSave, document, collectionName)); return objectToSave; - }).orElseGet(() -> { - doInsert(collectionName, objectToSave, this.mongoConverter); - return objectToSave; - }); + } + + doInsert(collectionName, objectToSave, this.mongoConverter); + return objectToSave; } protected T doSave(String collectionName, T objectToSave, MongoWriter writer) { @@ -1188,8 +1184,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, public UpdateResult doInCollection(MongoCollection collection) throws MongoException, DataAccessException { - Optional> entity = entityClass == null ? Optional.empty() - : getPersistentEntity(entityClass); + MongoPersistentEntity entity = entityClass == null ? null : getPersistentEntity(entityClass); increaseVersionForUpdateIfNecessary(entity, update); @@ -1235,24 +1230,26 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, }); } - private void increaseVersionForUpdateIfNecessary(Optional> persistentEntity, - Update update) { + private void increaseVersionForUpdateIfNecessary(MongoPersistentEntity persistentEntity, Update update) { - ifAllPresent(persistentEntity, persistentEntity.flatMap(PersistentEntity::getVersionProperty), - (entity, property) -> { - String versionFieldName = property.getFieldName(); - if (!update.modifies(versionFieldName)) { - update.inc(versionFieldName, 1L); - } - }); + if (persistentEntity != null && persistentEntity.hasVersionProperty()) { + String versionFieldName = persistentEntity.getRequiredVersionProperty().getFieldName(); + if (!update.modifies(versionFieldName)) { + update.inc(versionFieldName, 1L); + } + } } - private boolean documentContainsVersionProperty(Document document, - Optional> persistentEntity) { + private boolean documentContainsVersionProperty(Document document, MongoPersistentEntity persistentEntity) { - return mapIfAllPresent(persistentEntity, persistentEntity.flatMap(PersistentEntity::getVersionProperty), // - (entity, property) -> document.containsKey(property.getFieldName()))// - .orElse(false); + if (persistentEntity != null && persistentEntity.hasVersionProperty()) { + + MongoPersistentProperty property = persistentEntity.getRequiredVersionProperty(); + + return document.containsKey(property.getFieldName()); + } + + return false; } public DeleteResult remove(Object object) { @@ -1282,21 +1279,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * @param object * @return */ - private Pair> extractIdPropertyAndValue(Object object) { + private Pair extractIdPropertyAndValue(Object object) { Assert.notNull(object, "Id cannot be extracted from 'null'."); Class objectType = object.getClass(); if (object instanceof Document) { - return Pair.of(ID_FIELD, Optional.ofNullable(((Document) object).get(ID_FIELD))); + return Pair.of(ID_FIELD, ((Document) object).get(ID_FIELD)); } - Optional> entity = mappingContext.getPersistentEntity(objectType); - return mapIfAllPresent(entity, entity.flatMap(it -> it.getIdProperty()), // + MongoPersistentEntity entity = mappingContext.getPersistentEntity(objectType); - (l, r) -> Pair.of(r.getFieldName(), l.getPropertyAccessor(object).getProperty(r)))// - .orElseThrow(() -> new MappingException("No id property found for object of type " + objectType)); + if (entity != null && entity.hasIdProperty()) { + + MongoPersistentProperty idProperty = entity.getIdProperty(); + return Pair.of(idProperty.getFieldName(), entity.getPropertyAccessor(object).getProperty(idProperty)); + } + + throw new MappingException("No id property found for object of type " + objectType); } /** @@ -1307,8 +1308,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, */ private Query getIdQueryFor(Object object) { - Pair> id = extractIdPropertyAndValue(object); - return new Query(where(id.getFirst()).is(id.getSecond().orElse(null))); + Pair id = extractIdPropertyAndValue(object); + return new Query(where(id.getFirst()).is(id.getSecond())); } /** @@ -1322,13 +1323,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, Assert.notEmpty(objects, "Cannot create Query for empty collection."); Iterator it = objects.iterator(); - Pair> pair = extractIdPropertyAndValue(it.next()); + Pair pair = extractIdPropertyAndValue(it.next()); ArrayList ids = new ArrayList(objects.size()); - ids.add(pair.getSecond().orElse(null)); + ids.add(pair.getSecond()); while (it.hasNext()) { - ids.add(extractIdPropertyAndValue(it.next()).getSecond().orElse(null)); + ids.add(extractIdPropertyAndValue(it.next()).getSecond()); } return new Query(where(pair.getFirst()).in(ids)); @@ -1336,15 +1337,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, private void assertUpdateableIdIfNotSet(Object value) { - Optional> persistentEntity = mappingContext - .getPersistentEntity(value.getClass()); - Optional idProperty = persistentEntity.flatMap(it -> it.getIdProperty()); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(value.getClass()); - Optionals.ifAllPresent(persistentEntity, idProperty, (entity, property) -> { + if (entity != null && entity.hasIdProperty()) { - Optional propertyValue = entity.getPropertyAccessor(value).getProperty(property); + MongoPersistentProperty property = entity.getRequiredIdProperty(); + Object propertyValue = entity.getPropertyAccessor(value).getProperty(property); - if (propertyValue.isPresent()) { + if (propertyValue != null) { return; } @@ -1353,7 +1353,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, String.format("Cannot autogenerate id of type %s for entity of type %s!", property.getType().getName(), value.getClass().getName())); } - }); + } } public DeleteResult remove(Query query, String collectionName) { @@ -1377,7 +1377,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, Assert.hasText(collectionName, "Collection name must not be null or empty!"); final Document queryObject = query.getQueryObject(); - final Optional> entity = getPersistentEntity(entityClass); + final MongoPersistentEntity entity = getPersistentEntity(entityClass); return execute(collectionName, new CollectionCallback() { @@ -1948,7 +1948,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, */ protected T doFindOne(String collectionName, Document query, Document fields, Class entityClass) { - Optional> entity = mappingContext.getPersistentEntity(entityClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); Document mappedQuery = queryMapper.getMappedObject(query, entity); Document mappedFields = fields == null ? null : queryMapper.getMappedObject(fields, entity); @@ -1998,7 +1998,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, protected List doFind(String collectionName, Document query, Document fields, Class entityClass, CursorPreparer preparer, DocumentCallback objectCallback) { - Optional> entity = mappingContext.getPersistentEntity(entityClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); Document mappedFields = queryMapper.getMappedFields(fields, entity); Document mappedQuery = queryMapper.getMappedObject(query, entity); @@ -2069,7 +2069,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, serializeToJsonSafely(query), fields, sort, entityClass, collectionName); } - Optional> entity = mappingContext.getPersistentEntity(entityClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); return executeFindOneInternal( new FindAndRemoveCallback(queryMapper.getMappedObject(query, entity), fields, sort, collation), @@ -2085,7 +2085,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, options = new FindAndModifyOptions(); } - Optional> entity = mappingContext.getPersistentEntity(entityClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); increaseVersionForUpdateIfNecessary(entity, update); @@ -2121,17 +2121,19 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return; } - getIdPropertyFor(savedObject.getClass()).ifPresent(idProp -> { + MongoPersistentProperty idProperty = getIdPropertyFor(savedObject.getClass()); + + if (idProperty != null) { ConversionService conversionService = mongoConverter.getConversionService(); MongoPersistentEntity entity = mappingContext.getRequiredPersistentEntity(savedObject.getClass()); PersistentPropertyAccessor accessor = entity.getPropertyAccessor(savedObject); - Optional value = accessor.getProperty(idProp); - if (!value.isPresent()) { - new ConvertingPropertyAccessor(accessor, conversionService).setProperty(idProp, Optional.of(id)); + Object value = accessor.getProperty(idProperty); + if (value == null) { + new ConvertingPropertyAccessor(accessor, conversionService).setProperty(idProperty, id); } - }); + } } private MongoCollection getAndPrepareCollection(MongoDatabase db, String collectionName) { @@ -2262,12 +2264,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return exceptionTranslator; } - private Optional> getPersistentEntity(Class type) { - return Optional.ofNullable(type).flatMap(mappingContext::getPersistentEntity); + private MongoPersistentEntity getPersistentEntity(Class type) { + return type != null ? mappingContext.getPersistentEntity(type) : null; } - private Optional getIdPropertyFor(Class type) { - return mappingContext.getPersistentEntity(type).flatMap(PersistentEntity::getIdProperty); + private MongoPersistentProperty getIdPropertyFor(Class type) { + + MongoPersistentEntity persistentEntity = getPersistentEntity(type); + return persistentEntity != null ? persistentEntity.getIdProperty() : null; } private String determineEntityCollectionName(T obj) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java index 0f98dc592..f520a7713 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java @@ -22,17 +22,8 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -59,11 +50,10 @@ import org.springframework.data.convert.EntityReader; import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResult; import org.springframework.data.geo.Metric; -import org.springframework.data.mapping.PersistentEntity; 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.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory; import org.springframework.data.mongodb.core.convert.DbRefProxyHandler; @@ -94,6 +84,7 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.util.MongoClientVersion; import org.springframework.data.util.Optionals; +import org.springframework.data.util.Pair; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -615,8 +606,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati */ public Mono findById(Object id, Class entityClass, String collectionName) { - Optional> persistentEntity = mappingContext.getPersistentEntity(entityClass); - MongoPersistentProperty idProperty = persistentEntity.flatMap(PersistentEntity::getIdProperty).orElse(null); + MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(entityClass); + MongoPersistentProperty idProperty = persistentEntity != null ? persistentEntity.getIdProperty() : null; String idKey = idProperty == null ? ID_FIELD : idProperty.getName(); @@ -764,7 +755,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati final Document Document = query == null ? null : queryMapper.getMappedObject(query.getQueryObject(), - entityClass == null ? Optional.empty() : mappingContext.getPersistentEntity(entityClass)); + entityClass == null ? null : mappingContext.getPersistentEntity(entityClass)); return collection.count(Document); }); @@ -971,29 +962,28 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati ConvertingPropertyAccessor convertingAccessor = new ConvertingPropertyAccessor( entity.getPropertyAccessor(objectToSave), mongoConverter.getConversionService()); - MongoPersistentProperty idProperty = entity.getIdProperty() - .orElseThrow(() -> new IllegalArgumentException("No id property present!")); - MongoPersistentProperty versionProperty = entity.getVersionProperty() - .orElseThrow(() -> new IllegalArgumentException("No version property present!")); - ; + MongoPersistentProperty idProperty = entity.getRequiredIdProperty(); + MongoPersistentProperty versionProperty = entity.getRequiredVersionProperty(); - Optional version = convertingAccessor.getProperty(versionProperty); - Optional versionNumber = convertingAccessor.getProperty(versionProperty, Number.class); + Object version = convertingAccessor.getProperty(versionProperty); + Number versionNumber = convertingAccessor.getProperty(versionProperty, Number.class); // Fresh instance -> initialize version property - if (!version.isPresent()) { + if (version == null) { return doInsert(collectionName, objectToSave, mongoConverter); } - ReactiveMongoTemplate.this.assertUpdateableIdIfNotSet(objectToSave); + assertUpdateableIdIfNotSet(objectToSave); // Create query for entity with the id and old version - Optional id = convertingAccessor.getProperty(idProperty); - Query query = new Query( - Criteria.where(idProperty.getName()).is(id.get()).and(versionProperty.getName()).is(version.get())); + Object id = convertingAccessor.getProperty(idProperty); + Query query = new Query(Criteria.where(idProperty.getName()).is(id).and(versionProperty.getName()).is(version)); + if (versionNumber == null) { + versionNumber = 0; + } // Bump version number - convertingAccessor.setProperty(versionProperty, Optional.of(versionNumber.orElse(0).longValue() + 1)); + convertingAccessor.setProperty(versionProperty, versionNumber.longValue() + 1); ReactiveMongoTemplate.this.maybeEmitEvent(new BeforeConvertEvent(objectToSave, collectionName)); @@ -1241,7 +1231,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati private void increaseVersionForUpdateIfNecessary(MongoPersistentEntity persistentEntity, Update update) { if (persistentEntity != null && persistentEntity.hasVersionProperty()) { - String versionFieldName = persistentEntity.getVersionProperty().get().getFieldName(); + String versionFieldName = persistentEntity.getRequiredVersionProperty().getFieldName(); if (!update.modifies(versionFieldName)) { update.inc(versionFieldName, 1L); } @@ -1254,7 +1244,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati return false; } - return document.containsKey(persistentEntity.getVersionProperty().get().getFieldName()); + return document.containsKey(persistentEntity.getRequiredIdProperty().getFieldName()); } /* (non-Javadoc) @@ -1306,25 +1296,27 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * @param object * @return */ - private Entry extractIdPropertyAndValue(Object object) { + private Pair extractIdPropertyAndValue(Object object) { + + Assert.notNull(object, "Id cannot be extracted from 'null'."); Assert.notNull(object, "Id cannot be extracted from 'null'."); Class objectType = object.getClass(); if (object instanceof Document) { - return Collections.singletonMap(ID_FIELD, ((Document) object).get(ID_FIELD)).entrySet().iterator().next(); + return Pair.of(ID_FIELD, ((Document) object).get(ID_FIELD)); } - Optional> entity = mappingContext.getPersistentEntity(objectType); - MongoPersistentProperty idProp = entity.flatMap(PersistentEntity::getIdProperty).orElse(null); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(objectType); - if (idProp == null) { - throw new MappingException("No id property found for object of type " + objectType); + if (entity != null && entity.hasIdProperty()) { + + MongoPersistentProperty idProperty = entity.getIdProperty(); + return Pair.of(idProperty.getFieldName(), entity.getPropertyAccessor(object).getProperty(idProperty)); } - Optional idValue = entity.get().getPropertyAccessor(object).getProperty(idProp); - return Collections.singletonMap(idProp.getFieldName(), idValue.get()).entrySet().iterator().next(); + throw new MappingException("No id property found for object of type " + objectType); } /** @@ -1335,8 +1327,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati */ private Query getIdQueryFor(Object object) { - Entry id = extractIdPropertyAndValue(object); - return new Query(where(id.getKey()).is(id.getValue())); + Pair id = extractIdPropertyAndValue(object); + return new Query(where(id.getFirst()).is(id.getSecond())); } /** @@ -1350,35 +1342,36 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati Assert.notEmpty(objects, "Cannot create Query for empty collection."); Iterator it = objects.iterator(); - Entry firstEntry = extractIdPropertyAndValue(it.next()); + Pair firstEntry = extractIdPropertyAndValue(it.next()); ArrayList ids = new ArrayList(objects.size()); - ids.add(firstEntry.getValue()); + ids.add(firstEntry.getSecond()); while (it.hasNext()) { - ids.add(extractIdPropertyAndValue(it.next()).getValue()); + ids.add(extractIdPropertyAndValue(it.next()).getSecond()); } - return new Query(where(firstEntry.getKey()).in(ids)); + return new Query(where(firstEntry.getFirst()).in(ids)); } - private void assertUpdateableIdIfNotSet(Object entity) { + private void assertUpdateableIdIfNotSet(Object value) { - Optional> persistentEntity = mappingContext - .getPersistentEntity(entity.getClass()); - Optional idProperty = persistentEntity.isPresent() ? persistentEntity.get().getIdProperty() - : Optional.empty(); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(value.getClass()); - if (!idProperty.isPresent()) { - return; - } + if (entity != null && entity.hasIdProperty()) { - Optional idValue = persistentEntity.get().getPropertyAccessor(entity).getProperty(idProperty.get()); + MongoPersistentProperty property = entity.getRequiredIdProperty(); + Object propertyValue = entity.getPropertyAccessor(value).getProperty(property); - if (!idValue.isPresent() && !MongoSimpleTypes.AUTOGENERATED_ID_TYPES.contains(idProperty.get().getType())) { - throw new InvalidDataAccessApiUsageException( - String.format("Cannot autogenerate id of type %s for entity of type %s!", - idProperty.get().getType().getName(), entity.getClass().getName())); + if (propertyValue != null) { + return; + } + + if (!MongoSimpleTypes.AUTOGENERATED_ID_TYPES.contains(property.getType())) { + throw new InvalidDataAccessApiUsageException( + String.format("Cannot autogenerate id of type %s for entity of type %s!", property.getType().getName(), + value.getClass().getName())); + } } } @@ -1557,7 +1550,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati protected Mono doFindOne(String collectionName, Document query, Document fields, Class entityClass, Collation collation) { - Optional> entity = mappingContext.getPersistentEntity(entityClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); Document mappedQuery = queryMapper.getMappedObject(query, entity); Document mappedFields = fields == null ? null : queryMapper.getMappedObject(fields, entity); @@ -1607,7 +1600,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati protected Flux doFind(String collectionName, Document query, Document fields, Class entityClass, FindPublisherPreparer preparer, DocumentCallback objectCallback) { - Optional> entity = mappingContext.getPersistentEntity(entityClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); Document mappedFields = queryMapper.getMappedFields(fields, entity); Document mappedQuery = queryMapper.getMappedObject(query, entity); @@ -1654,7 +1647,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati serializeToJsonSafely(query), fields, sort, entityClass, collectionName)); } - Optional> entity = mappingContext.getPersistentEntity(entityClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); return executeFindOneInternal( new FindAndRemoveCallback(queryMapper.getMappedObject(query, entity), fields, sort, collation), @@ -1666,11 +1659,11 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati FindAndModifyOptions optionsToUse = options != null ? options : new FindAndModifyOptions(); - Optional> entity = mappingContext.getPersistentEntity(entityClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); return Mono.defer(() -> { - increaseVersionForUpdateIfNecessary(entity.get(), update); + increaseVersionForUpdateIfNecessary(entity, update); Document mappedQuery = queryMapper.getMappedObject(query, entity); Document mappedUpdate = updateMapper.getMappedObject(update.getUpdateObject(), entity); @@ -1721,11 +1714,11 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati MongoPersistentEntity entity = mappingContext.getRequiredPersistentEntity(savedObject.getClass()); PersistentPropertyAccessor accessor = entity.getPropertyAccessor(savedObject); - if (accessor.getProperty(idProp).isPresent()) { + if (accessor.getProperty(idProp) != null) { return; } - new ConvertingPropertyAccessor(accessor, conversionService).setProperty(idProp, Optional.ofNullable(id)); + new ConvertingPropertyAccessor(accessor, conversionService).setProperty(idProp, id); } private MongoCollection getAndPrepareCollection(MongoDatabase db, String collectionName) { @@ -1896,13 +1889,13 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati } private MongoPersistentEntity getPersistentEntity(Class type) { - return type == null ? null : mappingContext.getPersistentEntity(type).orElse(null); + return type == null ? null : mappingContext.getPersistentEntity(type); } private MongoPersistentProperty getIdPropertyFor(Class type) { - Optional> persistentEntity = mappingContext.getPersistentEntity(type); - return persistentEntity.flatMap(PersistentEntity::getIdProperty).orElse(null); + MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(type); + return persistentEntity != null ? persistentEntity.getIdProperty() : null; } private String determineEntityCollectionName(T obj) { @@ -1976,7 +1969,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati if (mongoPersistentEntity != null && mongoPersistentEntity.hasVersionProperty()) { ConvertingPropertyAccessor accessor = new ConvertingPropertyAccessor( mongoPersistentEntity.getPropertyAccessor(entity), mongoConverter.getConversionService()); - accessor.setProperty(mongoPersistentEntity.getVersionProperty().get(), Optional.of(0)); + accessor.setProperty(mongoPersistentEntity.getRequiredVersionProperty(), 0); } } @@ -2349,9 +2342,9 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati static class NoOpDbRefResolver implements DbRefResolver { @Override - public Optional resolveDbRef(MongoPersistentProperty property, DBRef dbref, DbRefResolverCallback callback, + public Object resolveDbRef(MongoPersistentProperty property, DBRef dbref, DbRefResolverCallback callback, DbRefProxyHandler proxyHandler) { - return Optional.empty(); + return null; } @Override diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolver.java index 6e19ef670..5ba5592ff 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,9 @@ */ package org.springframework.data.mongodb.core.convert; -import org.bson.Document; import java.util.List; -import java.util.Optional; +import org.bson.Document; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; @@ -27,7 +26,7 @@ import com.mongodb.DBRef; /** * Used to resolve associations annotated with {@link org.springframework.data.mongodb.core.mapping.DBRef}. - * + * * @author Thomas Darimont * @author Oliver Gierke * @author Christoph Strobl @@ -40,19 +39,19 @@ public interface DbRefResolver { * Resolves the given {@link DBRef} into an object of the given {@link MongoPersistentProperty}'s type. The method * might return a proxy object for the {@link DBRef} or resolve it immediately. In both cases the * {@link DbRefResolverCallback} will be used to obtain the actual backing object. - * + * * @param property will never be {@literal null}. * @param dbref the {@link DBRef} to resolve. * @param callback will never be {@literal null}. * @return */ - Optional resolveDbRef(MongoPersistentProperty property, DBRef dbref, DbRefResolverCallback callback, + Object resolveDbRef(MongoPersistentProperty property, DBRef dbref, DbRefResolverCallback callback, DbRefProxyHandler proxyHandler); /** * Creates a {@link DBRef} instance for the given {@link org.springframework.data.mongodb.core.mapping.DBRef} * annotation, {@link MongoPersistentEntity} and id. - * + * * @param annotation will never be {@literal null}. * @param entity will never be {@literal null}. * @param id will never be {@literal null}. @@ -63,7 +62,7 @@ public interface DbRefResolver { /** * Actually loads the {@link DBRef} from the datasource. - * + * * @param dbRef must not be {@literal null}. * @return * @since 1.7 diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefProxyHandler.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefProxyHandler.java index 837232cf3..00e832b25 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefProxyHandler.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefProxyHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import com.mongodb.DBRef; /** * @author Oliver Gierke * @author Christoph Strobl + * @author Mark Paluch */ class DefaultDbRefProxyHandler implements DbRefProxyHandler { @@ -50,7 +51,7 @@ class DefaultDbRefProxyHandler implements DbRefProxyHandler { this.resolver = resolver; } - /* + /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.convert.DbRefProxyHandler#populateId(com.mongodb.DBRef, java.lang.Object) */ @@ -62,8 +63,7 @@ class DefaultDbRefProxyHandler implements DbRefProxyHandler { } MongoPersistentEntity entity = mappingContext.getRequiredPersistentEntity(property); - MongoPersistentProperty idProperty = entity.getIdProperty() - .orElseThrow(() -> new IllegalStateException("Couldn't find identifier property!")); + MongoPersistentProperty idProperty = entity.getRequiredIdProperty(); if (idProperty.usePropertyAccess()) { return proxy; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java index 68f03be88..e74bfddf9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.Optional; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; @@ -55,7 +54,7 @@ import com.mongodb.client.model.Filters; /** * A {@link DbRefResolver} that resolves {@link org.springframework.data.mongodb.core.mapping.DBRef}s by delegating to a * {@link DbRefResolverCallback} than is able to generate lazy loading proxies. - * + * * @author Thomas Darimont * @author Oliver Gierke * @author Christoph Strobl @@ -70,7 +69,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Creates a new {@link DefaultDbRefResolver} with the given {@link MongoDbFactory}. - * + * * @param mongoDbFactory must not be {@literal null}. */ public DefaultDbRefResolver(MongoDbFactory mongoDbFactory) { @@ -87,20 +86,20 @@ public class DefaultDbRefResolver implements DbRefResolver { * @see org.springframework.data.mongodb.core.convert.DbRefResolver#resolveDbRef(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, org.springframework.data.mongodb.core.convert.DbRefResolverCallback) */ @Override - public Optional resolveDbRef(MongoPersistentProperty property, DBRef dbref, DbRefResolverCallback callback, + public Object resolveDbRef(MongoPersistentProperty property, DBRef dbref, DbRefResolverCallback callback, DbRefProxyHandler handler) { Assert.notNull(property, "Property must not be null!"); Assert.notNull(callback, "Callback must not be null!"); if (isLazyDbRef(property)) { - return Optional.of(createLazyLoadingProxy(property, dbref, callback, handler)); + return createLazyLoadingProxy(property, dbref, callback, handler); } - return Optional.ofNullable(callback.resolve(property)); + return callback.resolve(property); } - /* + /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.convert.DbRefResolver#created(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, org.springframework.data.mongodb.core.mapping.MongoPersistentEntity, java.lang.Object) */ @@ -165,7 +164,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Creates a proxy for the given {@link MongoPersistentProperty} using the given {@link DbRefResolverCallback} to * eventually resolve the value of the property. - * + * * @param property must not be {@literal null}. * @param dbref can be {@literal null}. * @param callback must not be {@literal null}. @@ -200,7 +199,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Returns the CGLib enhanced type for the given source type. - * + * * @param type * @return */ @@ -216,7 +215,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Returns whether the property shall be resolved lazily. - * + * * @param property must not be {@literal null}. * @return */ @@ -228,7 +227,7 @@ public class DefaultDbRefResolver implements DbRefResolver { * A {@link MethodInterceptor} that is used within a lazy loading proxy. The property resolving is delegated to a * {@link DbRefResolverCallback}. The resolving process is triggered by a method invocation on the proxy and is * guaranteed to be performed only once. - * + * * @author Thomas Darimont * @author Oliver Gierke * @author Christoph Strobl @@ -259,7 +258,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Creates a new {@link LazyLoadingInterceptor} for the given {@link MongoPersistentProperty}, * {@link PersistenceExceptionTranslator} and {@link DbRefResolverCallback}. - * + * * @param property must not be {@literal null}. * @param dbref can be {@literal null}. * @param callback must not be {@literal null}. @@ -286,7 +285,7 @@ public class DefaultDbRefResolver implements DbRefResolver { return intercept(invocation.getThis(), invocation.getMethod(), invocation.getArguments(), null); } - /* + /* * (non-Javadoc) * @see org.springframework.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], org.springframework.cglib.proxy.MethodProxy) */ @@ -332,7 +331,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Returns a to string representation for the given {@code proxy}. - * + * * @param proxy * @return */ @@ -353,7 +352,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Returns the hashcode for the given {@code proxy}. - * + * * @param proxy * @return */ @@ -363,7 +362,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Performs an equality check for the given {@code proxy}. - * + * * @param proxy * @param that * @return @@ -383,7 +382,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Will trigger the resolution if the proxy is not resolved already or return a previously resolved result. - * + * * @return */ private Object ensureResolved() { @@ -398,7 +397,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Callback method for serialization. - * + * * @param out * @throws IOException */ @@ -410,7 +409,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Callback method for deserialization. - * + * * @param in * @throws IOException */ @@ -426,7 +425,7 @@ public class DefaultDbRefResolver implements DbRefResolver { /** * Resolves the proxy into its backing object. - * + * * @return */ private synchronized Object resolve() { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolverCallback.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolverCallback.java index 93491d496..6a0c33cde 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolverCallback.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolverCallback.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,9 +22,10 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; /** * Default implementation of {@link DbRefResolverCallback}. - * + * * @author Oliver Gierke * @author Christoph Strobl + * @author Mark Paluch */ class DefaultDbRefResolverCallback implements DbRefResolverCallback { @@ -36,7 +37,7 @@ class DefaultDbRefResolverCallback implements DbRefResolverCallback { /** * Creates a new {@link DefaultDbRefResolverCallback} using the given {@link Document}, {@link ObjectPath}, * {@link ValueResolver} and {@link SpELExpressionEvaluator}. - * + * * @param surroundingObject must not be {@literal null}. * @param path must not be {@literal null}. * @param evaluator must not be {@literal null}. @@ -51,12 +52,12 @@ class DefaultDbRefResolverCallback implements DbRefResolverCallback { this.evaluator = evaluator; } - /* + /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.convert.DbRefResolverCallback#resolve(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty) */ @Override public Object resolve(MongoPersistentProperty property) { - return resolver.getValueInternal(property, surroundingObject, evaluator, path).orElse(null); + return resolver.getValueInternal(property, surroundingObject, evaluator, path); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java index 7e8fbb1ee..663bea394 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2016 the original author or authors. + * Copyright 2011-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,17 +32,17 @@ import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; +import org.springframework.util.ObjectUtils; import com.mongodb.BasicDBList; import com.mongodb.DBObject; -import org.springframework.util.ObjectUtils; /** * Default implementation of {@link MongoTypeMapper} allowing configuration of the key to lookup and store type * information in {@link Document}. The key defaults to {@link #DEFAULT_TYPE_KEY}. Actual type-to-{@link String} * conversion and back is done in {@link #getTypeString(TypeInformation)} or {@link #getTypeInformation(String)} * respectively. - * + * * @author Oliver Gierke * @author Thomas Darimont * @author Christoph Strobl @@ -94,7 +94,7 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper implements M return typeKey == null ? false : typeKey.equals(key); } - /* + /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.convert.MongoTypeMapper#writeTypeRestrictions(java.util.Set) */ @@ -111,26 +111,26 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper implements M Alias typeAlias = getAliasFor(ClassTypeInformation.from(restrictedType)); - if (typeAlias != null && !ObjectUtils.nullSafeEquals(Alias.NONE, typeAlias) && typeAlias.getValue().isPresent()) { - restrictedMappedTypes.add(typeAlias.getValue().get()); + if (typeAlias != null && !ObjectUtils.nullSafeEquals(Alias.NONE, typeAlias) && typeAlias.isPresent()) { + restrictedMappedTypes.add(typeAlias.getValue()); } } accessor.writeTypeTo(result, new Document("$in", restrictedMappedTypes)); } - /* + /* * (non-Javadoc) * @see org.springframework.data.convert.DefaultTypeMapper#getFallbackTypeFor(java.lang.Object) */ @Override - protected Optional> getFallbackTypeFor(Bson source) { - return Optional.of(source instanceof BasicDBList ? LIST_TYPE_INFO : MAP_TYPE_INFO); + protected TypeInformation getFallbackTypeFor(Bson source) { + return source instanceof BasicDBList ? LIST_TYPE_INFO : MAP_TYPE_INFO; } /** * {@link TypeAliasAccessor} to store aliases in a {@link Document}. - * + * * @author Oliver Gierke */ public static final class DocumentTypeAliasAccessor implements TypeAliasAccessor { @@ -152,9 +152,9 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper implements M } if (source instanceof Document) { - return Alias.ofOptional(Optional.ofNullable(((Document) source).get(typeKey))); + return Alias.ofNullable(((Document) source).get(typeKey)); } else if (source instanceof DBObject) { - return Alias.ofOptional(Optional.ofNullable(((DBObject) source).get(typeKey))); + return Alias.ofNullable(((DBObject) source).get(typeKey)); } throw new IllegalArgumentException("Cannot read alias from " + source.getClass()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java index 58d3adc4d..88d6e68a0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DocumentAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,6 @@ package org.springframework.data.mongodb.core.convert; import java.util.Arrays; import java.util.Iterator; import java.util.Map; -import java.util.Optional; -import java.util.function.Supplier; import org.bson.Document; import org.bson.conversions.Bson; @@ -34,9 +32,10 @@ import com.mongodb.DBObject; * Wrapper value object for a {@link Document} to be able to access raw values by {@link MongoPersistentProperty} * references. The accessors will transparently resolve nested document values that a {@link MongoPersistentProperty} * might refer to through a path expression in field names. - * + * * @author Oliver Gierke * @author Christoph Strobl + * @author Mark Paluch */ class DocumentAccessor { @@ -44,7 +43,7 @@ class DocumentAccessor { /** * Creates a new {@link DocumentAccessor} for the given {@link Document}. - * + * * @param document must be a {@link Document} effectively, must not be {@literal null}. */ public DocumentAccessor(Bson document) { @@ -62,7 +61,7 @@ class DocumentAccessor { * Puts the given value into the backing {@link Document} based on the coordinates defined through the given * {@link MongoPersistentProperty}. By default this will be the plain field name. But field names might also consist * of path traversals so we might need to create intermediate {@link BasicDocument}s. - * + * * @param prop must not be {@literal null}. * @param value */ @@ -91,20 +90,11 @@ class DocumentAccessor { } } - public void computeIfAbsent(MongoPersistentProperty prop, Supplier> supplier) { - - if (hasValue(prop)) { - return; - } - - supplier.get().ifPresent(it -> put(prop, it)); - } - /** * Returns the value the given {@link MongoPersistentProperty} refers to. By default this will be a direct field but * the method will also transparently resolve nested values the {@link MongoPersistentProperty} might refer to through * a path expression in the field name metadata. - * + * * @param property must not be {@literal null}. * @return */ @@ -161,7 +151,7 @@ class DocumentAccessor { if (this.document instanceof Document) { source = ((Document) this.document); - }else { + } else { source = ((DBObject) this.document).toMap(); } @@ -182,7 +172,7 @@ class DocumentAccessor { /** * Returns the given source object as map, i.e. {@link Document}s and maps as is or {@literal null} otherwise. - * + * * @param source can be {@literal null}. * @return */ @@ -207,7 +197,7 @@ class DocumentAccessor { /** * Returns the {@link Document} which either already exists in the given source under the given key, or creates a new * nested one, registers it with the source and returns it. - * + * * @param key must not be {@literal null} or empty. * @param source must not be {@literal null}. * @return diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index 5ba341bdd..032c0e83f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -15,8 +15,17 @@ */ package org.springframework.data.mongodb.core.convert; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; import org.bson.Document; import org.bson.conversions.Bson; @@ -30,14 +39,14 @@ import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.convert.EntityInstantiator; import org.springframework.data.convert.TypeMapper; -import org.springframework.data.mapping.AssociationHandler; +import org.springframework.data.mapping.Association; +import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PreferredConstructor.Parameter; -import org.springframework.data.mapping.PropertyHandler; 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.MappingException; import org.springframework.data.mapping.model.ParameterValueProvider; import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider; import org.springframework.data.mapping.model.PropertyValueProvider; @@ -52,7 +61,6 @@ import org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent; import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; -import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -82,9 +90,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App protected static final Logger LOGGER = LoggerFactory.getLogger(MappingMongoConverter.class); protected final MappingContext, MongoPersistentProperty> mappingContext; - protected final SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); protected final QueryMapper idMapper; protected final DbRefResolver dbRefResolver; + protected final DefaultDbRefProxyHandler dbRefProxyHandler; protected ApplicationContext applicationContext; protected MongoTypeMapper typeMapper; @@ -112,6 +120,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App this.idMapper = new QueryMapper(this); this.spELContext = new SpELContext(DocumentPropertyAccessor.INSTANCE); + this.dbRefProxyHandler = new DefaultDbRefProxyHandler(spELContext, mappingContext, MappingMongoConverter.this); } /** @@ -248,66 +257,89 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App private S read(final MongoPersistentEntity entity, final Document bson, final ObjectPath path) { - final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(bson, spELContext); + DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(bson, spELContext); ParameterValueProvider provider = getParameterProvider(entity, bson, evaluator, path); EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity); S instance = instantiator.createInstance(entity, provider); - final PersistentPropertyAccessor accessor = new ConvertingPropertyAccessor(entity.getPropertyAccessor(instance), + PersistentPropertyAccessor accessor = new ConvertingPropertyAccessor(entity.getPropertyAccessor(instance), conversionService); - final Optional idProperty = entity.getIdProperty(); - final S result = instance; + MongoPersistentProperty idProperty = entity.getIdProperty(); DocumentAccessor documentAccessor = new DocumentAccessor(bson); // make sure id property is set before all other properties - Optional idValue = idProperty.filter(documentAccessor::hasValue).map(it -> { + Object idValue = null; - Optional value = getValueInternal(it, bson, evaluator, path); - accessor.setProperty(it, value); + if (idProperty != null && documentAccessor.hasValue(idProperty)) { - return value; - }); + idValue = readIdValue(path, evaluator, idProperty, documentAccessor); + accessor.setProperty(idProperty, idValue); + } - final ObjectPath currentPath = path.push(result, entity, - idValue.isPresent() ? idProperty.map(it -> bson.get(it.getFieldName())).orElse(null) : null); + ObjectPath currentPath = path.push(instance, entity, idValue != null ? bson.get(idProperty.getFieldName()) : null); - // Set properties not already set in the constructor - entity.doWithProperties((PropertyHandler) prop -> { + MongoDbPropertyValueProvider valueProvider = new MongoDbPropertyValueProvider(documentAccessor, evaluator, + currentPath); + DbRefResolverCallback callback = new DefaultDbRefResolverCallback(bson, currentPath, evaluator, + MappingMongoConverter.this); + readProperties(entity, accessor, idProperty, documentAccessor, valueProvider, callback); + + return instance; + } + + private Object readIdValue(ObjectPath path, DefaultSpELExpressionEvaluator evaluator, + MongoPersistentProperty idProperty, DocumentAccessor documentAccessor) { + + String expression = idProperty.getSpelExpression(); + Object resolvedValue = expression != null ? evaluator.evaluate(expression) : documentAccessor.get(idProperty); + + return resolvedValue != null ? readValue(resolvedValue, idProperty.getTypeInformation(), path) : null; + } + + private void readProperties(MongoPersistentEntity entity, PersistentPropertyAccessor accessor, + MongoPersistentProperty idProperty, DocumentAccessor documentAccessor, + MongoDbPropertyValueProvider valueProvider, DbRefResolverCallback callback) { + + + for (MongoPersistentProperty prop : entity) { + + if(prop.isAssociation() && !entity.isConstructorArgument(prop)) { + readAssociation(prop.getAssociation(), accessor, documentAccessor, dbRefProxyHandler, callback ); + continue; + } // we skip the id property since it was already set if (idProperty != null && idProperty.equals(prop)) { - return; + continue; } if (entity.isConstructorArgument(prop) || !documentAccessor.hasValue(prop)) { - return; + continue; } - accessor.setProperty(prop, getValueInternal(prop, bson, evaluator, currentPath)); - }); + if(prop.isAssociation()) { + readAssociation(prop.getAssociation(), accessor, documentAccessor, dbRefProxyHandler, callback ); + continue; + } - // Handle associations - entity.doWithAssociations((AssociationHandler) association -> { + accessor.setProperty(prop, valueProvider.getPropertyValue(prop)); + } + } - final MongoPersistentProperty property = association.getInverse(); + private void readAssociation(Association association, PersistentPropertyAccessor accessor, + DocumentAccessor documentAccessor, DbRefProxyHandler handler, DbRefResolverCallback callback) { + + MongoPersistentProperty property = association.getInverse(); Object value = documentAccessor.get(property); - if (value == null || entity.isConstructorArgument(property)) { + if (value == null) { return; } DBRef dbref = value instanceof DBRef ? (DBRef) value : null; - - DbRefProxyHandler handler = new DefaultDbRefProxyHandler(spELContext, mappingContext, MappingMongoConverter.this); - DbRefResolverCallback callback = new DefaultDbRefResolverCallback(bson, currentPath, evaluator, - MappingMongoConverter.this); - accessor.setProperty(property, dbRefResolver.resolveDbRef(property, dbref, callback, handler)); - }); - - return result; } /* @@ -348,8 +380,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App Object target = obj instanceof LazyLoadingProxy ? ((LazyLoadingProxy) obj).getTarget() : obj; - writeInternal(target, bson, Optional.of(type)); - if (asMap(bson).containsKey("_is") && asMap(bson).get("_id") == null) { + writeInternal(target, bson, type); + if (asMap(bson).containsKey("_id") && asMap(bson).get("_id") == null) { removeFromMap(bson, "_id"); } @@ -366,7 +398,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * @param bson */ @SuppressWarnings("unchecked") - protected void writeInternal(final Object obj, final Bson bson, final Optional> typeHint) { + protected void writeInternal(final Object obj, final Bson bson, final TypeInformation typeHint) { if (null == obj) { return; @@ -387,7 +419,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } if (Collection.class.isAssignableFrom(entityType)) { - writeCollectionInternal((Collection) obj, Optional.of(ClassTypeInformation.LIST), (BasicDBList) bson); + writeCollectionInternal((Collection) obj, ClassTypeInformation.LIST, (BasicDBList) bson); return; } @@ -406,46 +438,65 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App throw new MappingException("No mapping metadata found for entity of type " + obj.getClass().getName()); } - final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(obj); + PersistentPropertyAccessor accessor = entity.getPropertyAccessor(obj); DocumentAccessor dbObjectAccessor = new DocumentAccessor(bson); - Optional idProperty = entity.getIdProperty(); - idProperty.ifPresent( - prop -> dbObjectAccessor.computeIfAbsent(prop, () -> idMapper.convertId(accessor.getProperty(prop)))); + MongoPersistentProperty idProperty = entity.getIdProperty(); + if (idProperty != null && !dbObjectAccessor.hasValue(idProperty)) { + + Object value = idMapper.convertId(accessor.getProperty(idProperty)); + + if (value != null) { + dbObjectAccessor.put(idProperty, value); + } + } + writeProperties(bson, entity, accessor, dbObjectAccessor, idProperty); + } + + private void writeProperties(Bson bson, MongoPersistentEntity entity, PersistentPropertyAccessor accessor, + DocumentAccessor dbObjectAccessor, MongoPersistentProperty idProperty) { // Write the properties - entity.doWithProperties((PropertyHandler) prop -> { + for (MongoPersistentProperty prop : entity) { - if (idProperty.map(it -> it.equals(prop)).orElse(false) || !prop.isWritable()) { - return; + + if (prop.equals(idProperty) || !prop.isWritable()) { + continue; + } + if(prop.isAssociation()) { + writeAssociation(prop.getAssociation(), accessor, dbObjectAccessor); + continue; } - accessor.getProperty(prop).ifPresent(it -> { - if (!conversions.isSimpleType(it.getClass())) { + Object value = accessor.getProperty(prop); - writePropertyInternal(it, bson, prop); - } else { - writeSimpleInternal(it, bson, prop); - } - }); - }); + if (value == null) { + continue; + } - entity.doWithAssociations((AssociationHandler) association -> { + if (!conversions.isSimpleType(value.getClass())) { + writePropertyInternal(value, dbObjectAccessor, prop); + } else { + writeSimpleInternal(value, bson, prop); + } + } + } + + private void writeAssociation(Association association, PersistentPropertyAccessor accessor, + DocumentAccessor dbObjectAccessor) { MongoPersistentProperty inverseProp = association.getInverse(); - accessor.getProperty(inverseProp).ifPresent(it -> writePropertyInternal(it, bson, inverseProp)); - }); + + writePropertyInternal(accessor.getProperty(inverseProp), dbObjectAccessor, inverseProp); } @SuppressWarnings({ "unchecked" }) - protected void writePropertyInternal(Object obj, Bson bson, MongoPersistentProperty prop) { + protected void writePropertyInternal(Object obj, DocumentAccessor accessor, MongoPersistentProperty prop) { if (obj == null) { return; } - DocumentAccessor accessor = new DocumentAccessor(bson); - TypeInformation valueType = ClassTypeInformation.from(obj.getClass()); TypeInformation type = prop.getTypeInformation(); @@ -497,14 +548,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App return; } - Object existingValue = accessor.get(prop); - Document document = existingValue instanceof Document ? (Document) existingValue : new Document(); - MongoPersistentEntity entity = isSubtype(prop.getType(), obj.getClass()) ? mappingContext.getRequiredPersistentEntity(obj.getClass()) : mappingContext.getRequiredPersistentEntity(type); + Object existingValue = accessor.get(prop); + Document document = existingValue instanceof Document ? (Document) existingValue : new Document(); + writeInternal(obj, document, entity); - addCustomTypeKeyIfNecessary(Optional.of(ClassTypeInformation.from(prop.getRawType())), obj, document); + addCustomTypeKeyIfNecessary(ClassTypeInformation.from(prop.getRawType()), obj, document); accessor.put(prop, document); } @@ -539,7 +590,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App protected List createCollection(Collection collection, MongoPersistentProperty property) { if (!property.isDbReference()) { - return writeCollectionInternal(collection, Optional.of(property.getTypeInformation()), new BasicDBList()); + return writeCollectionInternal(collection, property.getTypeInformation(), new BasicDBList()); } List dbList = new ArrayList<>(collection.size()); @@ -601,10 +652,13 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * @param sink the {@link BasicDBList} to write to. * @return */ - private BasicDBList writeCollectionInternal(Collection source, Optional> type, - BasicDBList sink) { + private BasicDBList writeCollectionInternal(Collection source, TypeInformation type, BasicDBList sink) { - Optional> componentType = type.flatMap(TypeInformation::getComponentType); + TypeInformation componentType = null; + + if (type != null) { + componentType = type.getComponentType(); + } for (Object element : source) { @@ -649,8 +703,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App writeCollectionInternal(asCollection(val), propertyType.getMapValueType(), new BasicDBList())); } else { Document document = new Document(); - Optional> valueTypeInfo = propertyType.isMap() ? propertyType.getMapValueType() - : Optional.of(ClassTypeInformation.OBJECT); + TypeInformation valueTypeInfo = propertyType.isMap() ? propertyType.getMapValueType() + : ClassTypeInformation.OBJECT; writeInternal(val, document, valueTypeInfo); addToMap(bson, simpleKey, document); } @@ -736,10 +790,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * @param value must not be {@literal null}. * @param bson must not be {@literal null}. */ - protected void addCustomTypeKeyIfNecessary(Optional> type, Object value, Bson bson) { + protected void addCustomTypeKeyIfNecessary(TypeInformation type, Object value, Bson bson) { - Optional> actualType = type.map(TypeInformation::getActualType).map(TypeInformation::getType); - Class reference = actualType.orElse(Object.class); + Class reference = type != null ? type.getActualType().getType() : Object.class; Class valueType = ClassUtils.getUserClass(value.getClass()); boolean notTheSameClass = !valueType.equals(reference); @@ -779,18 +832,19 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App Optional> customTarget = conversions.getCustomWriteTarget(value.getClass()); - return customTarget.map(it -> (Object) conversionService.convert(value, it)).orElseGet(() -> { + if (customTarget.isPresent()) { + return conversionService.convert(value, customTarget.get()); + } - if (ObjectUtils.isArray(value)) { + if (ObjectUtils.isArray(value)) { - if (value instanceof byte[]) { - return value; - } - return asCollection(value); + if (value instanceof byte[]) { + return value; } + return asCollection(value); + } - return Enum.class.isAssignableFrom(value.getClass()) ? ((Enum) value).name() : value; - }); + return Enum.class.isAssignableFrom(value.getClass()) ? ((Enum) value).name() : value; } /** @@ -827,30 +881,30 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App return (DBRef) target; } - Optional> targetEntity = mappingContext.getPersistentEntity(target.getClass()); - targetEntity = targetEntity.isPresent() ? targetEntity : mappingContext.getPersistentEntity(property); + MongoPersistentEntity targetEntity = mappingContext.getPersistentEntity(target.getClass()); + targetEntity = targetEntity != null ? targetEntity : mappingContext.getPersistentEntity(property); if (null == targetEntity) { throw new MappingException("No mapping metadata found for " + target.getClass()); } - MongoPersistentEntity entity = targetEntity - .orElseThrow(() -> new MappingException("No mapping metadata found for " + target.getClass())); + MongoPersistentEntity entity = targetEntity; - Optional idProperty = entity.getIdProperty(); + MongoPersistentProperty idProperty = entity.getIdProperty(); - return idProperty.map(it -> { + if (idProperty != null) { - Object id = target.getClass().equals(it.getType()) ? target : entity.getPropertyAccessor(target).getProperty(it); + Object id = target.getClass().equals(idProperty.getType()) ? target + : entity.getPropertyAccessor(target).getProperty(idProperty); if (null == id) { throw new MappingException("Cannot create a reference to an object with a NULL id."); } - return dbRefResolver.createDbRef(property == null ? null : property.getDBRef(), entity, - idMapper.convertId(id instanceof Optional ? (Optional) id : Optional.ofNullable(id)).orElse(null)); + return dbRefResolver.createDbRef(property == null ? null : property.getDBRef(), entity, idMapper.convertId(id)); + } - }).orElseThrow(() -> new MappingException("No id property found on class " + entity.getType())); + throw new MappingException("No id property found on class " + entity.getType()); } /* @@ -858,7 +912,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * @see org.springframework.data.mongodb.core.convert.ValueResolver#getValueInternal(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, com.mongodb.Document, org.springframework.data.mapping.model.SpELExpressionEvaluator, java.lang.Object) */ @Override - public Optional getValueInternal(MongoPersistentProperty prop, Bson bson, SpELExpressionEvaluator evaluator, + public Object getValueInternal(MongoPersistentProperty prop, Bson bson, SpELExpressionEvaluator evaluator, ObjectPath path) { return new MongoDbPropertyValueProvider(bson, evaluator, path).getPropertyValue(prop); } @@ -879,7 +933,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App Class collectionType = targetType.getType(); - TypeInformation componentType = targetType.getComponentType().orElse(ClassTypeInformation.OBJECT); + TypeInformation componentType = targetType.getComponentType() != null ? targetType.getComponentType() + : ClassTypeInformation.OBJECT; Class rawComponentType = componentType.getType(); collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class; @@ -941,15 +996,17 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App Class mapType = typeMapper.readType(bson, type).getType(); - Optional> valueType = type.getMapValueType(); - Class rawKeyType = type.getComponentType().map(TypeInformation::getType).orElse(null); - Class rawValueType = type.getMapValueType().map(TypeInformation::getType).orElse(null); + TypeInformation keyType = type.getComponentType(); + TypeInformation valueType = type.getMapValueType(); + + Class rawKeyType = keyType != null ? keyType.getType() : null; + Class rawValueType = valueType != null ? valueType.getType() : null; Map sourceMap = asMap(bson); Map map = CollectionFactory.createMap(mapType, rawKeyType, sourceMap.keySet().size()); if (!DBRef.class.equals(rawValueType) && isCollectionOfDbRefWhereBulkFetchIsPossible(sourceMap.values())) { - bulkReadAndConvertDBRefMapIntoTarget(valueType.orElse(null), rawValueType, sourceMap, map); + bulkReadAndConvertDBRefMapIntoTarget(valueType, rawValueType, sourceMap, map); return map; } @@ -961,12 +1018,12 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App Object key = potentiallyUnescapeMapKey(entry.getKey()); - if (rawKeyType != null) { + if (rawKeyType != null && !rawKeyType.isAssignableFrom(key.getClass())) { key = conversionService.convert(key, rawKeyType); } Object value = entry.getValue(); - TypeInformation defaultedValueType = valueType.orElse(ClassTypeInformation.OBJECT); + TypeInformation defaultedValueType = valueType != null ? valueType : ClassTypeInformation.OBJECT; if (value instanceof Document) { map.put(key, read(defaultedValueType, (Document) value, path)); @@ -976,7 +1033,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App map.put(key, DBRef.class.equals(rawValueType) ? value : readAndConvertDBRef((DBRef) value, defaultedValueType, ObjectPath.ROOT, rawValueType)); } else if (value instanceof List) { - map.put(key, readCollectionOrArray(valueType.orElse(ClassTypeInformation.LIST), (List) value, path)); + map.put(key, + readCollectionOrArray(valueType != null ? valueType : ClassTypeInformation.LIST, (List) value, path)); } else { map.put(key, getPotentiallyConvertedSimpleRead(value, rawValueType)); } @@ -1098,7 +1156,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App if (obj instanceof Map) { - Map converted = new LinkedHashMap<>(((Map) obj).size(), 1); Document result = new Document(); for (Map.Entry entry : ((Map) obj).entrySet()) { @@ -1199,7 +1256,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * * @author Oliver Gierke */ - private class MongoDbPropertyValueProvider implements PropertyValueProvider { + class MongoDbPropertyValueProvider implements PropertyValueProvider { private final DocumentAccessor source; private final SpELExpressionEvaluator evaluator; @@ -1224,17 +1281,39 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App this.path = path; } + /** + * Creates a new {@link MongoDbPropertyValueProvider} for the given source, {@link SpELExpressionEvaluator} and + * {@link ObjectPath}. + * + * @param accessor must not be {@literal null}. + * @param evaluator must not be {@literal null}. + * @param path can be {@literal null}. + */ + public MongoDbPropertyValueProvider(DocumentAccessor accessor, SpELExpressionEvaluator evaluator, ObjectPath path) { + + Assert.notNull(accessor, "DocumentAccessor must no be null!"); + Assert.notNull(evaluator, "SpELExpressionEvaluator must not be null!"); + Assert.notNull(path, "ObjectPath must not be null!"); + + this.source = accessor; + this.evaluator = evaluator; + this.path = path; + } + /* * (non-Javadoc) * @see org.springframework.data.convert.PropertyValueProvider#getPropertyValue(org.springframework.data.mapping.PersistentProperty) */ - public Optional getPropertyValue(MongoPersistentProperty property) { - return Optional + public T getPropertyValue(MongoPersistentProperty property) { - .ofNullable(property.getSpelExpression()// - .map(evaluator::evaluate)// - .orElseGet(() -> source.get(property)))// - .map(it -> readValue(it, property.getTypeInformation(), path)); + String expression = property.getSpelExpression(); + Object value = expression != null ? evaluator.evaluate(expression) : source.get(property); + + if (value == null) { + return null; + } + + return readValue(value, property.getTypeInformation(), path); } } @@ -1275,7 +1354,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } @SuppressWarnings("unchecked") - private T readValue(Object value, TypeInformation type, ObjectPath path) { + T readValue(Object value, TypeInformation type, ObjectPath path) { Class rawType = type.getType(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java index 2e5314ade..e8bf01968 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoExampleMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 the original author or authors. + * Copyright 2015-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,17 +15,8 @@ */ package org.springframework.data.mongodb.core.convert; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; -import java.util.Stack; import java.util.regex.Pattern; import org.bson.Document; @@ -41,7 +32,6 @@ import org.springframework.data.mongodb.core.query.MongoRegexCreator; import org.springframework.data.mongodb.core.query.SerializationUtils; import org.springframework.data.repository.core.support.ExampleMatcherAccessor; import org.springframework.data.repository.query.parser.Part.Type; -import org.springframework.data.util.Optionals; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -99,8 +89,12 @@ public class MongoExampleMapper { Document reference = (Document) converter.convertToMongoType(example.getProbe()); - if(entity.getIdProperty().isPresent() && !entity.getIdentifierAccessor(example.getProbe()).getIdentifier().isPresent()) { - reference.remove(entity.getIdProperty().get().getFieldName()); + if (entity.getIdProperty() != null) { + + Object identifier = entity.getIdentifierAccessor(example.getProbe()).getIdentifier(); + if (identifier == null) { + reference.remove(entity.getIdProperty().getFieldName()); + } } ExampleMatcherAccessor matcherAccessor = new ExampleMatcherAccessor(example.getMatcher()); @@ -153,7 +147,7 @@ public class MongoExampleMapper { while (parts.hasNext()) { String part = parts.next(); - MongoPersistentProperty prop = entity.getPersistentProperty(part).orElse(null); + MongoPersistentProperty prop = entity.getPersistentProperty(part); if (prop == null) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ObjectPath.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ObjectPath.java index 8c583862a..5334c5761 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ObjectPath.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ObjectPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,7 @@ package org.springframework.data.mongodb.core.convert; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Optional; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.util.Assert; @@ -31,34 +29,36 @@ import org.springframework.util.StringUtils; *

* An immutable ordered set of target objects for {@link Document} to {@link Object} conversions. Object paths can be * constructed by the {@link #toObjectPath(Object)} method and extended via {@link #push(Object)}. - * + * * @author Thomas Darimont * @author Oliver Gierke + * @author Mark Paluch * @since 1.6 */ class ObjectPath { public static final ObjectPath ROOT = new ObjectPath(); - private final List items; + private final ObjectPathItem[] items; private ObjectPath() { - this.items = Collections.emptyList(); + this.items = new ObjectPathItem[0]; } /** * Creates a new {@link ObjectPath} from the given parent {@link ObjectPath} by adding the provided * {@link ObjectPathItem} to it. - * + * * @param parent can be {@literal null}. * @param item */ private ObjectPath(ObjectPath parent, ObjectPath.ObjectPathItem item) { - List items = new ArrayList(parent.items); - items.add(item); + ObjectPathItem[] items = new ObjectPathItem[parent.items.length + 1]; + System.arraycopy(parent.items, 0, items, 0, parent.items.length); + items[parent.items.length] = item; - this.items = Collections.unmodifiableList(items); + this.items = items; } /** @@ -81,7 +81,7 @@ class ObjectPath { /** * Returns the object with the given id and stored in the given collection if it's contained in the {@link ObjectPath} * . - * + * * @param id must not be {@literal null}. * @param collection must not be {@literal null} or empty. * @return @@ -113,25 +113,25 @@ class ObjectPath { /** * Returns the current object of the {@link ObjectPath} or {@literal null} if the path is empty. - * + * * @return */ - public Optional getCurrentObject() { - return items.isEmpty() ? Optional.empty() : Optional.of(items.get(items.size() - 1).getObject()); + public Object getCurrentObject() { + return items.length == 0 ? null : items[items.length - 1].getObject(); } - /* + /* * (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { - if (items.isEmpty()) { + if (items.length == 0) { return "[empty]"; } - List strings = new ArrayList(items.size()); + List strings = new ArrayList(items.length); for (ObjectPathItem item : items) { strings.add(item.object.toString()); @@ -142,7 +142,7 @@ class ObjectPath { /** * An item in an {@link ObjectPath}. - * + * * @author Thomas Darimont * @author Oliver Gierke */ @@ -154,7 +154,7 @@ class ObjectPath { /** * Creates a new {@link ObjectPathItem}. - * + * * @param object * @param idValue * @param collection diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java index 71a45319f..db1ca5e4f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java @@ -39,7 +39,7 @@ import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.data.mapping.context.InvalidPersistentPropertyPath; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.PersistentPropertyPath; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.core.convert.MappingMongoConverter.NestedDocument; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; @@ -122,7 +122,7 @@ public class QueryMapper { if (Query.isRestrictedTypeKey(key)) { @SuppressWarnings("unchecked") - Set> restrictedTypes = (Set>) BsonUtils.get(query, key); + Set> restrictedTypes = BsonUtils.get(query, key); this.converter.getTypeMapper().writeTypeRestrictions(result, restrictedTypes); continue; @@ -318,11 +318,11 @@ public class QueryMapper { String inKey = valueDbo.containsField("$in") ? "$in" : "$nin"; List ids = new ArrayList(); for (Object id : (Iterable) valueDbo.get(inKey)) { - ids.add(convertId(id).get()); + ids.add(convertId(id)); } resultDbo.put(inKey, ids); } else if (valueDbo.containsField("$ne")) { - resultDbo.put("$ne", convertId(valueDbo.get("$ne")).get()); + resultDbo.put("$ne", convertId(valueDbo.get("$ne"))); } else { return getMappedObject(resultDbo, Optional.empty()); } @@ -337,18 +337,18 @@ public class QueryMapper { String inKey = valueDbo.containsKey("$in") ? "$in" : "$nin"; List ids = new ArrayList(); for (Object id : (Iterable) valueDbo.get(inKey)) { - ids.add(convertId(id).orElse(null)); + ids.add(convertId(id)); } resultDbo.put(inKey, ids); } else if (valueDbo.containsKey("$ne")) { - resultDbo.put("$ne", convertId(valueDbo.get("$ne")).orElse(null)); + resultDbo.put("$ne", convertId(valueDbo.get("$ne"))); } else { return getMappedObject(resultDbo, Optional.empty()); } return resultDbo; } else { - return convertId(value).orElse(null); + return convertId(value); } } @@ -394,7 +394,7 @@ public class QueryMapper { MongoPersistentEntity entity = documentField.getPropertyEntity(); return entity.hasIdProperty() && (type.equals(DBRef.class) - || entity.getIdProperty().map(it -> it.getActualType().isAssignableFrom(type)).orElse(false)); + || entity.getRequiredIdProperty().getActualType().isAssignableFrom(type)); } /** @@ -461,7 +461,7 @@ public class QueryMapper { if (source instanceof DBRef) { DBRef ref = (DBRef) source; - return new DBRef(ref.getCollectionName(), convertId(ref.getId()).get()); + return new DBRef(ref.getCollectionName(), convertId(ref.getId())); } if (source instanceof Iterable) { @@ -537,31 +537,28 @@ public class QueryMapper { return converter.toDBRef(source, property); } - private Optional convertId(Object id) { - return convertId(Optional.ofNullable(id)); - } - /** * Converts the given raw id value into either {@link ObjectId} or {@link String}. * * @param id * @return */ - public Optional convertId(Optional id) { + public Object convertId(Object id) { - return id.map(it -> { + if (id == null) { + return null; + } - if (it instanceof String) { - return ObjectId.isValid(it.toString()) ? conversionService.convert(it, ObjectId.class) : it; - } + if (id instanceof String) { + return ObjectId.isValid(id.toString()) ? conversionService.convert(id, ObjectId.class) : id; + } - try { - return conversionService.canConvert(it.getClass(), ObjectId.class) - ? conversionService.convert(it, ObjectId.class) : delegateConvertToMongoType(it, null); - } catch (ConversionException o_O) { - return delegateConvertToMongoType(it, null); - } - }); + try { + return conversionService.canConvert(id.getClass(), ObjectId.class) ? conversionService.convert(id, ObjectId.class) + : delegateConvertToMongoType(id, null); + } catch (ConversionException o_O) { + return delegateConvertToMongoType(id, null); + } } /** @@ -836,9 +833,13 @@ public class QueryMapper { @Override public boolean isIdField() { - return entity.getIdProperty()// - .map(it -> it.getName().equals(name) || it.getFieldName().equals(name))// - .orElseGet(() -> DEFAULT_ID_NAMES.contains(name)); + MongoPersistentProperty idProperty = entity.getIdProperty(); + + if (idProperty != null) { + return idProperty.getName().equals(name) || idProperty.getFieldName().equals(name); + } + + return DEFAULT_ID_NAMES.contains(name); } /* @@ -857,7 +858,7 @@ public class QueryMapper { @Override public MongoPersistentEntity getPropertyEntity() { MongoPersistentProperty property = getProperty(); - return property == null ? null : mappingContext.getPersistentEntity(property).orElse(null); + return property == null ? null : mappingContext.getPersistentEntity(property); } /* @@ -883,15 +884,15 @@ public class QueryMapper { * * @return */ - private final Association findAssociation() { + private Association findAssociation() { if (this.path != null) { for (MongoPersistentProperty p : this.path) { - Optional> association = p.getAssociation(); + Association association = p.getAssociation(); - if (association.isPresent()) { - return association.get(); + if (association != null) { + return association; } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ValueResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ValueResolver.java index 006c18992..65830439c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ValueResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ValueResolver.java @@ -15,8 +15,6 @@ */ package org.springframework.data.mongodb.core.convert; -import java.util.Optional; - import org.bson.Document; import org.bson.conversions.Bson; import org.springframework.data.mapping.model.SpELExpressionEvaluator; @@ -24,7 +22,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; /** * Internal API to trigger the resolution of properties. - * + * * @author Oliver Gierke * @author Christoph Strobl */ @@ -33,13 +31,13 @@ interface ValueResolver { /** * Resolves the value for the given {@link MongoPersistentProperty} within the given {@link Document} using the given * {@link SpELExpressionEvaluator} and {@link ObjectPath}. - * + * * @param prop * @param bson * @param evaluator * @param parent * @return */ - Optional getValueInternal(MongoPersistentProperty prop, Bson bson, SpELExpressionEvaluator evaluator, + Object getValueInternal(MongoPersistentProperty prop, Bson bson, SpELExpressionEvaluator evaluator, ObjectPath path); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java index 0a7ce5f7d..ad4ae4d04 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java @@ -131,7 +131,7 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener entity) { - if (entity.findAnnotation(Document.class).isPresent()) { + if (entity.isAnnotationPresent(Document.class)) { for (IndexDefinitionHolder indexToCreate : indexResolver.resolveIndexFor(entity.getTypeInformation())) { createIndex(indexToCreate); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java index c9b464fe1..aba0a827e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java @@ -23,7 +23,6 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; @@ -33,7 +32,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.AssociationHandler; import org.springframework.data.mapping.PropertyHandler; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexResolver.TextIndexIncludeOptions.IncludeStrategy; import org.springframework.data.mongodb.core.index.TextIndexDefinition.TextIndexDefinitionBuilder; import org.springframework.data.mongodb.core.index.TextIndexDefinition.TextIndexedFieldSpec; @@ -94,7 +93,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver { public List resolveIndexForEntity(final MongoPersistentEntity root) { Assert.notNull(root, "Index cannot be resolved for given 'null' entity."); - Document document = root.findAnnotation(Document.class).orElseThrow(() -> new IllegalArgumentException("Given entity is not collection root.")); + Document document = root.findAnnotation(Document.class); Assert.notNull(document, "Given entity is not collection root."); final List indexInformation = new ArrayList(); @@ -255,20 +254,20 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver { indexDefinitionBuilder.withLanguageOverride(persistentProperty.getFieldName()); } - Optional indexed = persistentProperty.findAnnotation(TextIndexed.class); + TextIndexed indexed = persistentProperty.findAnnotation(TextIndexed.class); - if (includeOptions.isForce() || indexed.isPresent()|| persistentProperty.isEntity()) { + if (includeOptions.isForce() || indexed != null || persistentProperty.isEntity()) { String propertyDotPath = (StringUtils.hasText(dotPath) ? dotPath + "." : "") + persistentProperty.getFieldName(); - Float weight = indexed.isPresent() ? indexed.get().weight() + Float weight = indexed != null ? indexed.weight() : (includeOptions.getParentFieldSpec() != null ? includeOptions.getParentFieldSpec().getWeight() : 1.0F); if (persistentProperty.isEntity()) { TextIndexIncludeOptions optionsForNestedType = includeOptions; - if (!IncludeStrategy.FORCE.equals(includeOptions.getStrategy()) && indexed.isPresent()) { + if (!IncludeStrategy.FORCE.equals(includeOptions.getStrategy()) && indexed != null) { optionsForNestedType = new TextIndexIncludeOptions(IncludeStrategy.FORCE, new TextIndexedFieldSpec(propertyDotPath, weight)); } @@ -282,7 +281,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver { LOGGER.info(String.format("Potentially invalid index structure discovered. Breaking operation for %s.", entity.getName()), e); } - } else if (includeOptions.isForce() || indexed.isPresent()) { + } else if (includeOptions.isForce() || indexed != null) { indexDefinitionBuilder.onField(propertyDotPath, weight); } } @@ -304,18 +303,18 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver { MongoPersistentEntity entity) { List indexDefinitions = new ArrayList(); - Optional indexes = entity.findAnnotation(CompoundIndexes.class); + CompoundIndexes indexes = entity.findAnnotation(CompoundIndexes.class); - if (indexes.isPresent()) { - for (CompoundIndex index : indexes.get().value()) { + if (indexes != null) { + for (CompoundIndex index : indexes.value()) { indexDefinitions.add(createCompoundIndexDefinition(dotPath, fallbackCollection, index, entity)); } } - Optional index = entity.findAnnotation(CompoundIndex.class); + CompoundIndex index = entity.findAnnotation(CompoundIndex.class); - if (index.isPresent()) { - indexDefinitions.add(createCompoundIndexDefinition(dotPath, fallbackCollection, index.get(), entity)); + if (index != null) { + indexDefinitions.add(createCompoundIndexDefinition(dotPath, fallbackCollection, index, entity)); } return indexDefinitions; @@ -382,33 +381,33 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver { protected IndexDefinitionHolder createIndexDefinition(String dotPath, String collection, MongoPersistentProperty persitentProperty) { - Optional index = persitentProperty.findAnnotation(Indexed.class); + Indexed index = persitentProperty.findAnnotation(Indexed.class); - if(!index.isPresent()){ + if (index == null) { return null; } Index indexDefinition = new Index().on(dotPath, - IndexDirection.ASCENDING.equals(index.get().direction()) ? Sort.Direction.ASC : Sort.Direction.DESC); + IndexDirection.ASCENDING.equals(index.direction()) ? Sort.Direction.ASC : Sort.Direction.DESC); - if (!index.get().useGeneratedName()) { - indexDefinition.named(pathAwareIndexName(index.get().name(), dotPath, persitentProperty)); + if (!index.useGeneratedName()) { + indexDefinition.named(pathAwareIndexName(index.name(), dotPath, persitentProperty)); } - if (index.get().unique()) { + if (index.unique()) { indexDefinition.unique(); } - if (index.get().sparse()) { + if (index.sparse()) { indexDefinition.sparse(); } - if (index.get().background()) { + if (index.background()) { indexDefinition.background(); } - if (index.get().expireAfterSeconds() >= 0) { - indexDefinition.expire(index.get().expireAfterSeconds(), TimeUnit.SECONDS); + if (index.expireAfterSeconds() >= 0) { + indexDefinition.expire(index.expireAfterSeconds(), TimeUnit.SECONDS); } return new IndexDefinitionHolder(dotPath, indexDefinition, collection); @@ -426,21 +425,21 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver { protected IndexDefinitionHolder createGeoSpatialIndexDefinition(String dotPath, String collection, MongoPersistentProperty persistentProperty) { - Optional index = persistentProperty.findAnnotation(GeoSpatialIndexed.class); + GeoSpatialIndexed index = persistentProperty.findAnnotation(GeoSpatialIndexed.class); - if(!index.isPresent()) { + if (index == null) { return null; } GeospatialIndex indexDefinition = new GeospatialIndex(dotPath); - indexDefinition.withBits(index.get().bits()); - indexDefinition.withMin(index.get().min()).withMax(index.get().max()); + indexDefinition.withBits(index.bits()); + indexDefinition.withMin(index.min()).withMax(index.max()); - if (!index.get().useGeneratedName()) { - indexDefinition.named(pathAwareIndexName(index.get().name(), dotPath, persistentProperty)); + if (!index.useGeneratedName()) { + indexDefinition.named(pathAwareIndexName(index.name(), dotPath, persistentProperty)); } - indexDefinition.typed(index.get().type()).withBucketSize(index.get().bucketSize()).withAdditionalField(index.get().additionalField()); + indexDefinition.typed(index.type()).withBucketSize(index.bucketSize()).withAdditionalField(index.additionalField()); return new IndexDefinitionHolder(dotPath, indexDefinition, collection); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java index 6f50d93ac..1f397fa75 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java @@ -20,7 +20,6 @@ import java.lang.reflect.Modifier; import java.util.Comparator; import java.util.HashMap; import java.util.Map; -import java.util.Optional; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; @@ -32,7 +31,7 @@ import org.springframework.data.mapping.Association; import org.springframework.data.mapping.AssociationHandler; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.model.BasicPersistentEntity; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.MongoCollectionUtils; import org.springframework.data.util.TypeInformation; import org.springframework.expression.Expression; @@ -47,7 +46,7 @@ import org.springframework.util.StringUtils; /** * MongoDB specific {@link MongoPersistentEntity} implementation that adds Mongo specific meta-data such as the * collection name and the like. - * + * * @author Jon Brisbin * @author Oliver Gierke * @author Thomas Darimont @@ -69,23 +68,30 @@ public class BasicMongoPersistentEntity extends BasicPersistentEntity typeInformation) { - super(typeInformation, Optional.of(MongoPersistentPropertyComparator.INSTANCE)); + super(typeInformation, MongoPersistentPropertyComparator.INSTANCE); Class rawType = typeInformation.getType(); String fallback = MongoCollectionUtils.getPreferredCollectionName(rawType); - Optional document = this.findAnnotation(Document.class); - - this.expression = document.map(it -> detectExpression(it)).orElse(null); this.context = new StandardEvaluationContext(); - this.collection = document.filter(it -> StringUtils.hasText(it.collection())).map(it -> it.collection()) - .orElse(fallback); - this.language = document.filter(it -> StringUtils.hasText(it.language())).map(it -> it.language()).orElse(""); + + if (this.isAnnotationPresent(Document.class)) { + Document document = this.findAnnotation(Document.class); + + this.collection = StringUtils.hasText(document.collection()) ? document.collection() : fallback; + this.language = StringUtils.hasText(document.language()) ? document.language() : ""; + this.expression = document != null ? detectExpression(document) : null; + } else { + + this.collection = fallback; + this.language = ""; + this.expression = null; + } } /* @@ -122,7 +128,7 @@ public class BasicMongoPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity { @@ -189,7 +195,7 @@ public class BasicMongoPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity currentIdProperty = getIdProperty(); + MongoPersistentProperty currentIdProperty = getIdProperty(); - return currentIdProperty.map(it -> { + boolean currentIdPropertyIsSet = currentIdProperty != null; + @SuppressWarnings("null") + boolean currentIdPropertyIsExplicit = currentIdPropertyIsSet ? currentIdProperty.isExplicitIdProperty() : false; + boolean newIdPropertyIsExplicit = property.isExplicitIdProperty(); - boolean currentIdPropertyIsExplicit = it.isExplicitIdProperty(); - boolean newIdPropertyIsExplicit = property.isExplicitIdProperty(); - Optional currentIdPropertyField = it.getField(); + if (!currentIdPropertyIsSet) { + return property; - if (newIdPropertyIsExplicit && currentIdPropertyIsExplicit) { - throw new MappingException( - String.format( - "Attempt to add explicit id property %s but already have an property %s registered " - + "as explicit id. Check your mapping configuration!", - property.getField(), currentIdPropertyField)); + } - } else if (newIdPropertyIsExplicit && !currentIdPropertyIsExplicit) { - // explicit id property takes precedence over implicit id property - return property; + @SuppressWarnings("null") + Field currentIdPropertyField = currentIdProperty.getField(); - } else if (!newIdPropertyIsExplicit && currentIdPropertyIsExplicit) { - // no id property override - current property is explicitly defined + if (newIdPropertyIsExplicit && currentIdPropertyIsExplicit) { + throw new MappingException( + String.format("Attempt to add explicit id property %s but already have an property %s registered " + + "as explicit id. Check your mapping configuration!", property.getField(), currentIdPropertyField)); - } else { - throw new MappingException( - String.format("Attempt to add id property %s but already have an property %s registered " - + "as id. Check your mapping configuration!", property.getField(), currentIdPropertyField)); - } + } else if (newIdPropertyIsExplicit && !currentIdPropertyIsExplicit) { + // explicit id property takes precedence over implicit id property + return property; - return null; + } else if (!newIdPropertyIsExplicit && currentIdPropertyIsExplicit) { + // no id property override - current property is explicitly defined - }).orElse(property); + } else { + throw new MappingException( + String.format("Attempt to add id property %s but already have an property %s registered " + + "as id. Check your mapping configuration!", property.getField(), currentIdPropertyField)); + } + return null; } /** * Returns a SpEL {@link Expression} frór the collection String expressed in the given {@link Document} annotation if * present or {@literal null} otherwise. Will also return {@literal null} it the collection {@link String} evaluates * to a {@link LiteralExpression} (indicating that no subsequent evaluation is necessary). - * + * * @param document can be {@literal null} * @return */ @@ -264,7 +272,7 @@ public class BasicMongoPersistentEntity extends BasicPersistentEntity implements MongoPersistentProperty { @@ -65,7 +65,7 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope /** * Creates a new {@link BasicMongoPersistentProperty}. - * + * * @param field * @param propertyDescriptor * @param owner @@ -86,7 +86,7 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope /** * Also considers fields as id that are of supported id type and name. - * + * * @see #SUPPORTED_ID_PROPERTY_NAMES * @see #SUPPORTED_ID_TYPES */ @@ -113,14 +113,14 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope /** * Returns the key to be used to store the value of the property inside a Mongo {@link org.bson.Document}. - * + * * @return */ public String getFieldName() { if (isIdProperty()) { - if (!getOwner().getIdProperty().isPresent()) { + if (getOwner().getIdProperty() == null) { return ID_FIELD_NAME; } @@ -154,13 +154,10 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope private String getAnnotatedFieldName() { - Optional annotation = findAnnotation( + org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation( org.springframework.data.mongodb.core.mapping.Field.class); - return annotation// - .filter(it -> StringUtils.hasText(it.value()))// - .map(it -> it.value())// - .orElse(null); + return annotation != null ? annotation.value() : null; } /* @@ -169,10 +166,10 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope */ public int getFieldOrder() { - Optional annotation = findAnnotation( + org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation( org.springframework.data.mongodb.core.mapping.Field.class); - return annotation.map(it -> it.order()).orElse(Integer.MAX_VALUE); + return annotation != null ? annotation.order() : Integer.MAX_VALUE; } /* @@ -197,7 +194,7 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope * @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#getDBRef() */ public DBRef getDBRef() { - return findAnnotation(DBRef.class).orElse(null); + return findAnnotation(DBRef.class); } /* diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/EntityHandler.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/EntityHandler.java deleted file mode 100644 index 21c05a9dd..000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/EntityHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.core.mapping; - -import lombok.Value; - -import java.util.Optional; -import java.util.function.BiConsumer; - -import org.springframework.data.util.Optionals; - -/** - * @author Oliver Gierke - */ -@Value(staticConstructor = "of") -public class EntityHandler> { - - Optional entity; - - public void doWithVersionProperty(BiConsumer consumer) { - - Optionals.ifAllPresent(entity, entity.flatMap(it -> it.getVersionProperty()), consumer); - } -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/DtoInstantiatingConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/DtoInstantiatingConverter.java index f91491f95..613f7a00f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/DtoInstantiatingConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/DtoInstantiatingConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 the original author or authors. + * Copyright 2015-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,6 @@ */ package org.springframework.data.mongodb.repository.query; -import java.util.Optional; - import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.EntityInstantiator; import org.springframework.data.convert.EntityInstantiators; @@ -36,6 +34,7 @@ import org.springframework.util.Assert; * {@link Converter} to instantiate DTOs from fully equipped domain objects. * * @author Oliver Gierke + * @author Mark Paluch */ class DtoInstantiatingConverter implements Converter { @@ -45,7 +44,7 @@ class DtoInstantiatingConverter implements Converter { /** * Creates a new {@link Converter} to instantiate DTOs. - * + * * @param dtoType must not be {@literal null}. * @param context must not be {@literal null}. * @param instantiators must not be {@literal null}. @@ -63,7 +62,7 @@ class DtoInstantiatingConverter implements Converter { this.instantiator = instantiator.getInstantiatorFor(context.getRequiredPersistentEntity(dtoType)); } - /* + /* * (non-Javadoc) * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) */ @@ -78,14 +77,14 @@ class DtoInstantiatingConverter implements Converter { final PersistentPropertyAccessor sourceAccessor = sourceEntity.getPropertyAccessor(source); final PersistentEntity targetEntity = context.getRequiredPersistentEntity(targetType); final PreferredConstructor> constructor = targetEntity - .getPersistenceConstructor().get(); + .getPersistenceConstructor(); @SuppressWarnings({ "rawtypes", "unchecked" }) Object dto = instantiator.createInstance(targetEntity, new ParameterValueProvider() { @Override - public Optional getParameterValue(Parameter parameter) { - return sourceAccessor.getProperty(sourceEntity.getPersistentProperty(parameter.getName().get().toString()).get()); + public Object getParameterValue(Parameter parameter) { + return sourceAccessor.getProperty(sourceEntity.getPersistentProperty(parameter.getName().toString())); } }); @@ -101,7 +100,7 @@ class DtoInstantiatingConverter implements Converter { } dtoAccessor.setProperty(property, - sourceAccessor.getProperty(sourceEntity.getPersistentProperty(property.getName()).get())); + sourceAccessor.getProperty(sourceEntity.getPersistentProperty(property.getName()))); } }); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameters.java index 5c0ed54b1..60005a0b8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameters.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoParameters.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 the original author or authors. + * Copyright 2011-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ import org.springframework.data.util.TypeInformation; /** * Custom extension of {@link Parameters} discovering additional - * + * * @author Oliver Gierke * @author Christoph Strobl */ @@ -47,7 +47,7 @@ public class MongoParameters extends Parameters /** * Creates a new {@link MongoParameters} instance from the given {@link Method} and {@link MongoQueryMethod}. - * + * * @param method must not be {@literal null}. * @param queryMethod must not be {@literal null}. */ @@ -115,8 +115,8 @@ public class MongoParameters extends Parameters if (this.nearIndex == null && mongoParameter.isManuallyAnnotatedNearParameter()) { this.nearIndex = mongoParameter.getIndex(); } else if (mongoParameter.isManuallyAnnotatedNearParameter()) { - throw new IllegalStateException(String.format( - "Found multiple @Near annotations ond method %s! Only one allowed!", parameter.getMethod().toString())); + throw new IllegalStateException(String.format("Found multiple @Near annotations ond method %s! Only one allowed!", + parameter.getMethod().toString())); } return mongoParameter; @@ -128,7 +128,7 @@ public class MongoParameters extends Parameters /** * Returns the index of the {@link Distance} parameter to be used for max distance in geo queries. - * + * * @return * @since 1.7 */ @@ -138,7 +138,7 @@ public class MongoParameters extends Parameters /** * Returns the index of the parameter to be used to start a geo-near query from. - * + * * @return */ public int getNearIndex() { @@ -147,7 +147,7 @@ public class MongoParameters extends Parameters /** * Returns ths inde of the parameter to be used as a textquery param - * + * * @return * @since 1.6 */ @@ -171,7 +171,7 @@ public class MongoParameters extends Parameters return rangeIndex; } - /* + /* * (non-Javadoc) * @see org.springframework.data.repository.query.Parameters#createFrom(java.util.List) */ @@ -190,7 +190,7 @@ public class MongoParameters extends Parameters if (componentType == null) { return i; - } else if (componentType.equals(candidate.getComponentType().get().getType())) { + } else if (componentType.equals(candidate.getRequiredComponentType().getType())) { return i; } } @@ -201,7 +201,7 @@ public class MongoParameters extends Parameters /** * Custom {@link Parameter} implementation adding parameters of type {@link Distance} to the special ones. - * + * * @author Oliver Gierke */ class MongoParameter extends Parameter { @@ -210,7 +210,7 @@ public class MongoParameters extends Parameters /** * Creates a new {@link MongoParameter}. - * + * * @param parameter must not be {@literal null}. */ MongoParameter(MethodParameter parameter) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java index 69c1c2572..2478b9227 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java @@ -51,7 +51,7 @@ import org.springframework.util.ClassUtils; /** * Custom query creator to create Mongo criterias. - * + * * @author Oliver Gierke * @author Thomas Darimont * @author Christoph Strobl @@ -68,7 +68,7 @@ class MongoQueryCreator extends AbstractQueryCreator { /** * Creates a new {@link MongoQueryCreator} from the given {@link PartTree}, {@link ConvertingParameterAccessor} and * {@link MappingContext}. - * + * * @param tree * @param accessor * @param context @@ -81,7 +81,7 @@ class MongoQueryCreator extends AbstractQueryCreator { /** * Creates a new {@link MongoQueryCreator} from the given {@link PartTree}, {@link ConvertingParameterAccessor} and * {@link MappingContext}. - * + * * @param tree * @param accessor * @param context @@ -163,7 +163,7 @@ class MongoQueryCreator extends AbstractQueryCreator { /** * Populates the given {@link CriteriaDefinition} depending on the {@link Part} given. - * + * * @param part * @param property * @param criteria @@ -272,7 +272,7 @@ class MongoQueryCreator extends AbstractQueryCreator { /** * Creates and extends the given criteria with a like-regex if necessary. - * + * * @param part * @param property * @param criteria @@ -314,7 +314,7 @@ class MongoQueryCreator extends AbstractQueryCreator { * If the target property of the comparison is of type String, then the operator checks for match using regular * expression. If the target property of the comparison is a {@link Collection} then the operator evaluates to true if * it finds an exact match within any member of the {@link Collection}. - * + * * @param part * @param property * @param criteria @@ -333,7 +333,7 @@ class MongoQueryCreator extends AbstractQueryCreator { /** * Creates an appropriate like-regex and appends it to the given criteria. - * + * * @param criteria * @param part * @param value @@ -368,7 +368,7 @@ class MongoQueryCreator extends AbstractQueryCreator { /** * Returns the next element from the given {@link Iterator} expecting it to be of a certain type. - * + * * @param * @param iterator * @param type @@ -407,7 +407,11 @@ class MongoQueryCreator extends AbstractQueryCreator { private boolean isSpherical(MongoPersistentProperty property) { - Optional index = property.findAnnotation(GeoSpatialIndexed.class); - return index.isPresent() && index.get().type().equals(GeoSpatialIndexType.GEO_2DSPHERE); + if (property.isAnnotationPresent(GeoSpatialIndexed.class)) { + GeoSpatialIndexed index = property.findAnnotation(GeoSpatialIndexed.class); + return index.type().equals(GeoSpatialIndexType.GEO_2DSPHERE); + } + + return false; } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java index 401bcd162..f9ac79696 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,7 +62,7 @@ interface MongoQueryExecution { /** * {@link MongoQueryExecution} for collection returning queries. - * + * * @author Oliver Gierke */ @RequiredArgsConstructor @@ -83,7 +83,7 @@ interface MongoQueryExecution { /** * {@link MongoQueryExecution} for {@link Slice} query methods. - * + * * @author Oliver Gierke * @author Christoph Strobl * @since 1.5 @@ -116,7 +116,7 @@ interface MongoQueryExecution { /** * {@link MongoQueryExecution} for pagination queries. - * + * * @author Oliver Gierke * @author Mark Paluch */ @@ -154,7 +154,7 @@ interface MongoQueryExecution { /** * {@link MongoQueryExecution} to return a single entity. - * + * * @author Oliver Gierke */ @RequiredArgsConstructor @@ -217,7 +217,7 @@ interface MongoQueryExecution { /** * {@link MongoQueryExecution} to execute geo-near queries. - * + * * @author Oliver Gierke */ @RequiredArgsConstructor @@ -267,8 +267,8 @@ interface MongoQueryExecution { return false; } - Optional> componentType = returnType.getComponentType(); - return componentType.isPresent() && GeoResult.class.equals(componentType.get().getType()); + TypeInformation componentType = returnType.getComponentType(); + return componentType != null && GeoResult.class.equals(componentType.getType()); } } @@ -322,7 +322,7 @@ interface MongoQueryExecution { /** * {@link MongoQueryExecution} removing documents matching the query. - * + * * @since 1.5 */ @RequiredArgsConstructor @@ -388,7 +388,7 @@ interface MongoQueryExecution { private final @NonNull MongoQueryExecution delegate; private final @NonNull Converter converter; - /* + /* * (non-Javadoc) * @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String) */ @@ -411,7 +411,7 @@ interface MongoQueryExecution { private final @NonNull MongoOperations operations; private final @NonNull EntityInstantiators instantiators; - /* + /* * (non-Javadoc) * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) */ diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java index da40346a8..eb9c75635 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryMethod.java @@ -147,14 +147,14 @@ public class MongoQueryMethod extends QueryMethod { } else { - Optional> returnedEntity = mappingContext.getPersistentEntity(returnedObjectType); + MongoPersistentEntity returnedEntity = mappingContext.getPersistentEntity(returnedObjectType); MongoPersistentEntity managedEntity = mappingContext.getRequiredPersistentEntity(domainClass); - returnedEntity = !returnedEntity.isPresent() || returnedEntity.get().getType().isInterface() ? Optional.of(managedEntity) + returnedEntity = returnedEntity == null || returnedEntity.getType().isInterface() ? managedEntity : returnedEntity; - MongoPersistentEntity collectionEntity = domainClass.isAssignableFrom(returnedObjectType) ? returnedEntity.get() + MongoPersistentEntity collectionEntity = domainClass.isAssignableFrom(returnedObjectType) ? returnedEntity : managedEntity; - this.metadata = new SimpleMongoEntityMetadata((Class) returnedEntity.get().getType(), + this.metadata = new SimpleMongoEntityMetadata((Class) returnedEntity.getType(), collectionEntity); } } @@ -192,7 +192,7 @@ public class MongoQueryMethod extends QueryMethod { if (Iterable.class.isAssignableFrom(returnType)) { TypeInformation from = ClassTypeInformation.fromReturnTypeOf(method); - return GeoResult.class.equals(from.getComponentType().get().getType()); + return GeoResult.class.equals(from.getRequiredComponentType().getType()); } return false; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java index cc7baeb3d..4531927c9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryExecution.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,6 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; import reactor.core.publisher.Flux; -import java.util.Optional; - import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.EntityInstantiators; import org.springframework.data.domain.Pageable; @@ -154,8 +152,8 @@ interface ReactiveMongoQueryExecution { return false; } - Optional> componentType = returnType.getComponentType(); - return componentType.isPresent() && GeoResult.class.equals(componentType.get().getType()); + TypeInformation componentType = returnType.getComponentType(); + return componentType != null && GeoResult.class.equals(componentType.getType()); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java index add7c413e..f173f644d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ReactiveMongoQueryMethod.java @@ -70,8 +70,8 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod { boolean multiWrapper = ReactiveWrappers.isMultiValueType(returnType.getType()); boolean singleWrapperWithWrappedPageableResult = ReactiveWrappers.isSingleValueType(returnType.getType()) - && (PAGE_TYPE.isAssignableFrom(returnType.getComponentType().get()) - || SLICE_TYPE.isAssignableFrom(returnType.getComponentType().get())); + && (PAGE_TYPE.isAssignableFrom(returnType.getRequiredComponentType()) + || SLICE_TYPE.isAssignableFrom(returnType.getRequiredComponentType())); if (singleWrapperWithWrappedPageableResult) { throw new InvalidDataAccessApiUsageException( @@ -94,7 +94,7 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod { this.method = method; } - /* + /* * (non-Javadoc) * @see org.springframework.data.mongodb.repository.query.MongoQueryMethod#createParameters(java.lang.reflect.Method) */ @@ -103,7 +103,7 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod { return new MongoParameters(method, isGeoNearQuery(method)); } - /* + /* * (non-Javadoc) * @see org.springframework.data.repository.query.QueryMethod#isCollectionQuery() */ @@ -112,7 +112,7 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod { return !(isPageQuery() || isSliceQuery()) && ReactiveWrappers.isMultiValueType(method.getReturnType()); } - /* + /* * (non-Javadoc) * @see org.springframework.data.mongodb.repository.query.MongoQueryMethod#isGeoNearQuery() */ @@ -125,13 +125,13 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod { if (ReactiveWrappers.supports(method.getReturnType())) { TypeInformation from = ClassTypeInformation.fromReturnTypeOf(method); - return GeoResult.class.equals(from.getComponentType().get().getType()); + return GeoResult.class.equals(from.getRequiredComponentType().getType()); } return false; } - /* + /* * (non-Javadoc) * @see org.springframework.data.repository.query.QueryMethod#isModifyingQuery() */ @@ -140,7 +140,7 @@ public class ReactiveMongoQueryMethod extends MongoQueryMethod { return super.isModifyingQuery(); } - /* + /* * (non-Javadoc) * @see org.springframework.data.repository.query.QueryMethod#isQueryForEntity() */ diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java index 1cef31293..3f14f9da2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 by the original author(s). + * Copyright 2011-2017 by the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +24,10 @@ import org.springframework.data.repository.core.support.PersistentEntityInformat * {@link MongoEntityInformation} implementation using a {@link MongoPersistentEntity} instance to lookup the necessary * information. Can be configured with a custom collection to be returned which will trump the one returned by the * {@link MongoPersistentEntity} if given. - * + * * @author Oliver Gierke * @author Christoph Strobl + * @author Mark Paluch */ public class MappingMongoEntityInformation extends PersistentEntityInformation implements MongoEntityInformation { @@ -37,7 +38,7 @@ public class MappingMongoEntityInformation extends PersistentEntityInform /** * Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity}. - * + * * @param entity must not be {@literal null}. */ public MappingMongoEntityInformation(MongoPersistentEntity entity) { @@ -47,18 +48,18 @@ public class MappingMongoEntityInformation extends PersistentEntityInform /** * Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity} and fallback * identifier type. - * + * * @param entity must not be {@literal null}. * @param fallbackIdType can be {@literal null}. */ public MappingMongoEntityInformation(MongoPersistentEntity entity, Class fallbackIdType) { - this(entity, (String) null, fallbackIdType); + this(entity, null, fallbackIdType); } /** * Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity} and custom * collection name. - * + * * @param entity must not be {@literal null}. * @param customCollectionName can be {@literal null}. */ @@ -69,7 +70,7 @@ public class MappingMongoEntityInformation extends PersistentEntityInform /** * Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity}, collection name * and identifier type. - * + * * @param entity must not be {@literal null}. * @param customCollectionName can be {@literal null}. * @param idType can be {@literal null}. @@ -96,7 +97,7 @@ public class MappingMongoEntityInformation extends PersistentEntityInform * @see org.springframework.data.mongodb.repository.MongoEntityInformation#getIdAttribute() */ public String getIdAttribute() { - return entityMetadata.getIdProperty().get().getName(); + return entityMetadata.getRequiredIdProperty().getName(); } /* diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/PersistableMongoEntityInformation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/PersistableMongoEntityInformation.java index 97151cbee..c4b27219e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/PersistableMongoEntityInformation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/PersistableMongoEntityInformation.java @@ -18,8 +18,6 @@ package org.springframework.data.mongodb.repository.support; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import java.util.Optional; - import org.springframework.data.domain.Persistable; import org.springframework.data.mongodb.repository.query.MongoEntityInformation; @@ -76,10 +74,10 @@ class PersistableMongoEntityInformation implements MongoEntityInformation */ @Override @SuppressWarnings("unchecked") - public Optional getId(T t) { + public ID getId(T t) { if (t instanceof Persistable) { - return Optional.ofNullable(((Persistable) t).getId()); + return ((Persistable) t).getId(); } return delegate.getId(t); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java index b249d9635..bdd935176 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2016 the original author or authors. + * Copyright 2011-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,10 +33,10 @@ import org.springframework.util.ClassUtils; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.DBRef; +import com.mongodb.util.JSON; import com.querydsl.core.types.Constant; import com.querydsl.core.types.Expression; import com.querydsl.core.types.Operation; -import com.mongodb.util.JSON; import com.querydsl.core.types.Path; import com.querydsl.core.types.PathMetadata; import com.querydsl.core.types.PathType; @@ -44,7 +44,7 @@ import com.querydsl.mongodb.MongodbSerializer; /** * Custom {@link MongodbSerializer} to take mapping information into account when building keys for constraints. - * + * * @author Oliver Gierke * @author Christoph Strobl * @author Mark Paluch @@ -69,7 +69,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer { /** * Creates a new {@link SpringDataMongodbSerializer} for the given {@link MappingContext}. - * + * * @param mappingContext must not be {@literal null}. */ public SpringDataMongodbSerializer(MongoConverter converter) { @@ -108,9 +108,9 @@ class SpringDataMongodbSerializer extends MongodbSerializer { Path parent = metadata.getParent(); MongoPersistentEntity entity = mappingContext.getRequiredPersistentEntity(parent.getType()); - Optional property = entity.getPersistentProperty(metadata.getName()); + MongoPersistentProperty property = entity.getPersistentProperty(metadata.getName()); - return !property.isPresent() ? super.getKeyForPath(expr, metadata) : property.get().getFieldName(); + return property == null ? super.getKeyForPath(expr, metadata) : property.getFieldName(); } /* @@ -120,7 +120,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer { @Override protected DBObject asDBObject(String key, Object value) { - value = value instanceof Optional ? ((Optional)value).orElse(null) : value; + value = value instanceof Optional ? ((Optional) value).orElse(null) : value; if (ID_KEY.equals(key)) { DBObject superIdValue = super.asDBObject(key, value); @@ -203,8 +203,8 @@ class SpringDataMongodbSerializer extends MongodbSerializer { return null; } - Optional> entity = mappingContext.getPersistentEntity(parent.getType()); - return entity.isPresent() ? entity.get().getRequiredPersistentProperty(path.getMetadata().getName()) : null; + MongoPersistentEntity entity = mappingContext.getPersistentEntity(parent.getType()); + return entity != null ? entity.getRequiredPersistentProperty(path.getMetadata().getName()) : null; } /** diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsIntegrationTests.java index b0c749b45..1e8fb06c5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsIntegrationTests.java @@ -46,7 +46,7 @@ import com.mongodb.client.MongoCollection; /** * Integration tests for {@link DefaultBulkOperations}. - * + * * @author Tobias Trelle * @author Oliver Gierke * @author Christoph Strobl @@ -278,7 +278,7 @@ public class DefaultBulkOperationsIntegrationTests { private BulkOperations createBulkOps(BulkMode mode, Class entityType) { Optional> entity = entityType != null - ? operations.getConverter().getMappingContext().getPersistentEntity(entityType) : Optional.empty(); + ? Optional.of(operations.getConverter().getMappingContext().getPersistentEntity(entityType)) : Optional.empty(); BulkOperationContext bulkOperationContext = new BulkOperationContext(mode, entity, new QueryMapper(operations.getConverter()), new UpdateMapper(operations.getConverter())); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsUnitTests.java index dccd74491..755334d2d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultBulkOperationsUnitTests.java @@ -23,6 +23,7 @@ import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Query.*; import java.util.List; +import java.util.Optional; import org.bson.Document; import org.junit.Before; @@ -80,8 +81,9 @@ public class DefaultBulkOperationsUnitTests { when(template.getCollection(anyString())).thenReturn(collection); ops = new DefaultBulkOperations(template, "collection-1", - new BulkOperationContext(BulkMode.ORDERED, mappingContext.getPersistentEntity(SomeDomainType.class), - new QueryMapper(converter), new UpdateMapper(converter))); + new BulkOperationContext(BulkMode.ORDERED, + Optional.of(mappingContext.getPersistentEntity(SomeDomainType.class)), new QueryMapper(converter), + new UpdateMapper(converter))); } @Test // DATAMONGO-1518 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java index 97529ac2f..9705d299f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java @@ -29,6 +29,7 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.dao.DataAccessException; import org.springframework.data.geo.Point; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.convert.AbstractMongoConverter; import org.springframework.data.mongodb.core.convert.MongoConverter; @@ -210,7 +211,7 @@ public abstract class MongoOperationsUnitTests { public void doWith(MongoOperations operations) { operations.findAll(Object.class); } - }.assertException(IllegalArgumentException.class); + }.assertException(MappingException.class); } @Test diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index 3473112c7..4cdb3fbef 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -54,7 +54,7 @@ import org.springframework.data.convert.CustomConversions; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.convert.DbRefResolver; @@ -1498,7 +1498,7 @@ public class MongoTemplateTests { template.save(map, "maps"); } - @Test(expected = IllegalArgumentException.class) // DATAMONGO-549 + @Test(expected = MappingException.class) // DATAMONGO-549, DATAMONGO-1730 public void savesMongoPrimitiveObjectCorrectly() { template.save(new Object(), "collection"); } @@ -1517,7 +1517,7 @@ public class MongoTemplateTests { assertThat(document.containsKey("_id"), is(true)); } - @Test(expected = IllegalArgumentException.class) // DATAMONGO-550 + @Test(expected = MappingException.class) // DATAMONGO-550, DATAMONGO-1730 public void rejectsPlainObjectWithOutExplicitCollection() { org.bson.Document document = new org.bson.Document("foo", "bar"); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java index 0ae2b6cf0..926471745 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java @@ -51,7 +51,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.geo.Metrics; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.core.MongoTemplateTests.PersonWithConvertedId; import org.springframework.data.mongodb.core.MongoTemplateTests.VersionedPerson; import org.springframework.data.mongodb.core.index.GeoSpatialIndexType; @@ -86,6 +86,7 @@ public class ReactiveMongoTemplateTests { StepVerifier .create(template.dropCollection("people") // + .mergeWith(template.dropCollection("personX")) // .mergeWith(template.dropCollection("collection")) // .mergeWith(template.dropCollection(Person.class)) // .mergeWith(template.dropCollection(Venue.class)) // @@ -536,11 +537,11 @@ public class ReactiveMongoTemplateTests { StepVerifier.create(template.save(map, "maps")).expectNextCount(1).verifyComplete(); } - @Test // DATAMONGO-1444 + @Test // DATAMONGO-1444, DATAMONGO-1730 public void savesMongoPrimitiveObjectCorrectly() { StepVerifier.create(template.save(new Object(), "collection")) // - .expectError(IllegalArgumentException.class) // + .expectError(MappingException.class) // .verify(); } @@ -554,7 +555,7 @@ public class ReactiveMongoTemplateTests { assertThat(dbObject.containsKey("_id"), is(true)); } - @Test(expected = IllegalArgumentException.class) // DATAMONGO-1444 + @Test(expected = MappingException.class) // DATAMONGO-1444, DATAMONGO-1730 public void rejectsPlainObjectWithOutExplicitCollection() { Document dbObject = new Document("foo", "bar"); @@ -562,9 +563,8 @@ public class ReactiveMongoTemplateTests { StepVerifier.create(template.save(dbObject, "collection")).expectNextCount(1).verifyComplete(); StepVerifier.create(template.findById(dbObject.get("_id"), Document.class)) // - .expectError(IllegalArgumentException.class) // + .expectError(MappingException.class) // .verify(); - } @Test // DATAMONGO-1444 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java index 9d8e1c1ca..ff11059a5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java @@ -54,7 +54,7 @@ import org.springframework.dao.DataAccessException; import org.springframework.data.annotation.Id; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.geo.Metrics; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.core.CollectionCallback; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.Venue; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerIntegrationTests.java index 3710b6899..0325bd13f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerIntegrationTests.java @@ -24,7 +24,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.convert.DbRefResolver; import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContextUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContextUnitTests.java index 24210332b..f1d415e6a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContextUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/TypeBasedAggregationOperationContextUnitTests.java @@ -38,7 +38,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.convert.CustomConversions; import org.springframework.data.domain.Sort.Direction; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.core.aggregation.ExposedFields.DirectFieldReference; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java index fd0a36113..ef91c8e2d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DbRefMappingMongoConverterUnitTests.java @@ -18,6 +18,7 @@ package org.springframework.data.mongodb.core.convert; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; import static org.springframework.data.mongodb.core.convert.LazyLoadingTestUtils.*; import java.io.Serializable; @@ -68,6 +69,7 @@ import com.mongodb.client.MongoDatabase; * @author Oliver Gierke * @author Thomas Darimont * @author Christoph Strobl + * @author Mark Paluch */ @RunWith(MockitoJUnitRunner.class) public class DbRefMappingMongoConverterUnitTests { @@ -483,7 +485,7 @@ public class DbRefMappingMongoConverterUnitTests { PersistentPropertyAccessor accessor = propertyEntity.getPropertyAccessor(result.dbRefToConcreteType); MongoPersistentProperty idProperty = mappingContext.getRequiredPersistentEntity(LazyDbRefTarget.class) - .getIdProperty().get(); + .getIdProperty(); assertThat(accessor.getProperty(idProperty), is(notNullValue())); assertProxyIsResolved(result.dbRefToConcreteType, false); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapperUnitTests.java index 336c58119..bb0542e8e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DefaultMongoTypeMapperUnitTests.java @@ -21,7 +21,6 @@ import static org.junit.Assert.*; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Optional; import org.bson.Document; import org.junit.Before; @@ -33,7 +32,7 @@ import org.springframework.data.util.TypeInformation; /** * Unit tests for {@link DefaultMongoTypeMapper}. - * + * * @author Oliver Gierke */ public class DefaultMongoTypeMapperUnitTests { @@ -187,13 +186,13 @@ public class DefaultMongoTypeMapperUnitTests { private void readsTypeFromField(Document document, Class type) { - Optional> typeInfo = typeMapper.readType(document); + TypeInformation typeInfo = typeMapper.readType(document); if (type != null) { assertThat(typeInfo, is(notNullValue())); - assertThat(typeInfo.get().getType(), is(typeCompatibleWith(type))); + assertThat(typeInfo.getType(), is(typeCompatibleWith(type))); } else { - assertThat(typeInfo, is(Optional.empty())); + assertThat(typeInfo, is(nullValue())); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index 3774e9131..c9e110036 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -58,7 +58,7 @@ import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; import org.springframework.data.geo.Shape; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.model.MappingInstantiationException; import org.springframework.data.mongodb.core.DocumentTestUtils; import org.springframework.data.mongodb.core.convert.DocumentAccessorUnitTests.NestedType; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java index b074ec212..2b3a47711 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java @@ -36,7 +36,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; - import org.springframework.data.annotation.Id; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; @@ -462,7 +461,7 @@ public class QueryMapperUnitTests { public void queryMapperShouldNotChangeStateInGivenQueryObjectWhenIdConstrainedByInList() { BasicMongoPersistentEntity persistentEntity = context.getRequiredPersistentEntity(Sample.class); - String idPropertyName = persistentEntity.getIdProperty().get().getName(); + String idPropertyName = persistentEntity.getIdProperty().getName(); org.bson.Document queryObject = query(where(idPropertyName).in("42")).getQueryObject(); Object idValuesBefore = getAsDocument(queryObject, idPropertyName).get("$in"); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java index d378ae86f..9af4a9933 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java @@ -45,7 +45,7 @@ import org.springframework.data.convert.WritingConverter; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.domain.Sort.Order; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.DocumentTestUtils; import org.springframework.data.mongodb.core.mapping.Field; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntityUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntityUnitTests.java index c2773a3f5..9489143b7 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntityUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntityUnitTests.java @@ -30,7 +30,7 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.context.ApplicationContext; import org.springframework.core.annotation.AliasFor; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.util.ClassTypeInformation; /** diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java index 766d55e81..cc393112a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java @@ -33,7 +33,7 @@ import org.springframework.core.annotation.AliasFor; import org.springframework.data.annotation.Id; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.model.FieldNamingStrategy; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy; import org.springframework.data.mapping.model.SimpleTypeHolder; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MongoMappingContextUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MongoMappingContextUnitTests.java index 862307483..344b0e03b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MongoMappingContextUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MongoMappingContextUnitTests.java @@ -22,7 +22,6 @@ import java.util.AbstractMap; import java.util.Collections; import java.util.Locale; import java.util.Map; -import java.util.Optional; import org.junit.Rule; import org.junit.Test; @@ -34,16 +33,17 @@ import org.springframework.context.ApplicationContext; import org.springframework.data.annotation.Id; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.model.FieldNamingStrategy; -import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.MappingException; import com.mongodb.DBRef; /** * Unit tests for {@link MongoMappingContext}. - * + * * @author Oliver Gierke * @author Thomas Darimont * @author Christoph Strobl + * @author Mark Paluch */ @RunWith(MockitoJUnitRunner.class) public class MongoMappingContextUnitTests { @@ -65,14 +65,14 @@ public class MongoMappingContextUnitTests { public void doesNotReturnPersistentEntityForMongoSimpleType() { MongoMappingContext context = new MongoMappingContext(); - assertThat(context.getPersistentEntity(DBRef.class), is(Optional.empty())); + assertThat(context.getPersistentEntity(DBRef.class), is(nullValue())); } @Test // DATAMONGO-638 public void doesNotCreatePersistentEntityForAbstractMap() { MongoMappingContext context = new MongoMappingContext(); - assertThat(context.getPersistentEntity(AbstractMap.class), is(Optional.empty())); + assertThat(context.getPersistentEntity(AbstractMap.class), is(nullValue())); } @Test // DATAMONGO-607 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java index d428cfe1d..b8b01b1b0 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/performance/ReactivePerformanceTests.java @@ -22,18 +22,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Random; -import java.util.Set; +import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -107,9 +96,9 @@ public class ReactivePerformanceTests { converter = new MappingMongoConverter(new DbRefResolver() { @Override - public Optional resolveDbRef(MongoPersistentProperty property, DBRef dbref, + public Object resolveDbRef(MongoPersistentProperty property, DBRef dbref, DbRefResolverCallback callback, DbRefProxyHandler proxyHandler) { - return Optional.empty(); + return null; } @Override diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/AbstractMongoQueryUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/AbstractMongoQueryUnitTests.java index 6a97cbf6f..044d19f9c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/AbstractMongoQueryUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/AbstractMongoQueryUnitTests.java @@ -20,13 +20,10 @@ import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Date; import java.util.List; import java.util.Optional; import org.bson.Document; -import org.bson.types.ObjectId; import org.hamcrest.core.Is; import org.junit.Before; import org.junit.Test; @@ -81,7 +78,7 @@ public class AbstractMongoQueryUnitTests { public void setUp() { doReturn("persons").when(persitentEntityMock).getCollection(); - doReturn(Optional.of(persitentEntityMock)).when(mappingContextMock).getPersistentEntity(Mockito.any(Class.class)); + doReturn(persitentEntityMock).when(mappingContextMock).getPersistentEntity(Mockito.any(Class.class)); doReturn(persitentEntityMock).when(mappingContextMock).getRequiredPersistentEntity(Mockito.any(Class.class)); doReturn(Person.class).when(persitentEntityMock).getType(); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java index b7322abb1..0744185a9 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryTests.java @@ -24,7 +24,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -389,8 +388,8 @@ public class SimpleMongoRepositoryTests { } @Override - public Optional getId(Person entity) { - return Optional.ofNullable(entity.getId()); + public String getId(Person entity) { + return entity.getId(); } @Override