diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java index 8986e3b62..be84be882 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/EntityOperations.java @@ -177,6 +177,22 @@ class EntityOperations { return AdaptibleMappedEntity.of(entity, context, conversionService, this); } + /** + * Creates a new {@link AdaptibleEntity} for the given bean and {@link ConversionService} to be used for a save + * operation including a {@link AdaptibleEntity#assertUpdateableIdIfNotSet()} check. + * + * @param entity must not be {@literal null}. + * @param conversionService must not be {@literal null}. + * @return new instance of {@link AdaptibleEntity}. + * @since 4.5.9 + */ + AdaptibleEntity forEntityUpsert(T entity, ConversionService conversionService) { + + AdaptibleEntity adaptibleEntity = forEntity(entity, conversionService); + adaptibleEntity.assertUpdateableIdIfNotSet(); + return adaptibleEntity; + } + /** * @param source can be {@literal null}. * @return {@literal true} if the given value is an {@literal array}, {@link Collection} or {@link Iterator}. @@ -468,7 +484,7 @@ class EntityOperations { MappedDocument toMappedDocument(MongoWriter writer); /** - * Asserts that the identifier type is updatable in case its not already set. + * Asserts that the identifier type is updatable in case it is not already set. */ default void assertUpdateableIdIfNotSet() {} 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 4ee7979c3..9fb4c0407 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 @@ -1308,7 +1308,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, /** * Prepare the collection before any processing is done using it. This allows a convenient way to apply settings like - * withCodecRegistry() etc. Can be overridden in sub-classes. + * withCodecRegistry() etc. Can be overridden in subclasses. * * @param collection */ @@ -1323,9 +1323,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, /** * Prepare the WriteConcern before any processing is done using it. This allows a convenient way to apply custom - * settings in sub-classes.
- * In case of using MongoDB Java driver version 3 the returned {@link WriteConcern} will be defaulted to - * {@link WriteConcern#ACKNOWLEDGED} when {@link WriteResultChecking} is set to {@link WriteResultChecking#EXCEPTION}. + * settings in subclasses. In case of using MongoDB Java driver version 3 the returned {@link WriteConcern} will be + * defaulted to {@link WriteConcern#ACKNOWLEDGED} when {@link WriteResultChecking} is set to + * {@link WriteResultChecking#EXCEPTION}. * * @param mongoAction any MongoAction already configured or null * @return The prepared WriteConcern or null @@ -1355,9 +1355,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, T toConvert = maybeEmitEvent(event).getSource(); toConvert = maybeCallBeforeConvert(toConvert, collectionName); - AdaptibleEntity entity = operations.forEntity(toConvert, mongoConverter.getConversionService()); - entity.assertUpdateableIdIfNotSet(); - + AdaptibleEntity entity = operations.forEntityUpsert(toConvert, mongoConverter.getConversionService()); T initialized = entity.initializeVersionProperty(); Document dbDoc = entity.toMappedDocument(writer).getDocument(); @@ -1435,9 +1433,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, T toConvert = maybeEmitEvent(event).getSource(); toConvert = maybeCallBeforeConvert(toConvert, collectionName); - AdaptibleEntity entity = operations.forEntity(toConvert, mongoConverter.getConversionService()); - entity.assertUpdateableIdIfNotSet(); - + AdaptibleEntity entity = operations.forEntityUpsert(toConvert, mongoConverter.getConversionService()); T initialized = entity.initializeVersionProperty(); Document document = entity.toMappedDocument(writer).getDocument(); maybeEmitEvent(new BeforeSaveEvent<>(initialized, document, collectionName)); @@ -1538,9 +1534,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, objectToSave = maybeEmitEvent(new BeforeConvertEvent<>(objectToSave, collectionName)).getSource(); objectToSave = maybeCallBeforeConvert(objectToSave, collectionName); - AdaptibleEntity entity = operations.forEntity(objectToSave, mongoConverter.getConversionService()); - entity.assertUpdateableIdIfNotSet(); - + AdaptibleEntity entity = operations.forEntityUpsert(objectToSave, mongoConverter.getConversionService()); MappedDocument mapped = entity.toMappedDocument(writer); Document dbDoc = mapped.getDocument(); 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 6478cbf69..d8ca037e7 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 @@ -108,7 +108,6 @@ import org.springframework.data.mongodb.core.mapping.FieldName; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; -import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes; import org.springframework.data.mongodb.core.mapping.event.*; import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions; import org.springframework.data.mongodb.core.query.BasicQuery; @@ -1368,9 +1367,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati .flatMap(it -> maybeCallBeforeConvert(it.getSource(), it.getCollection()).map(it::mutate)) // .map(it -> { - AdaptibleEntity entity = operations.forEntity(it.getSource(), mongoConverter.getConversionService()); - entity.assertUpdateableIdIfNotSet(); - + AdaptibleEntity entity = operations.forEntityUpsert(it.getSource(), mongoConverter.getConversionService()); PersistableEntityModel model = PersistableEntityModel.of(entity.initializeVersionProperty(), entity.toMappedDocument(writer).getDocument(), it.getCollection()); @@ -1440,9 +1437,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati return maybeCallBeforeConvert(toConvert, collectionName).flatMap(it -> { - AdaptibleEntity entity = operations.forEntity(it, mongoConverter.getConversionService()); - entity.assertUpdateableIdIfNotSet(); - + AdaptibleEntity entity = operations.forEntityUpsert(it, mongoConverter.getConversionService()); T initialized = entity.initializeVersionProperty(); MappedDocument mapped = entity.toMappedDocument(writer); @@ -1558,9 +1553,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati return maybeCallBeforeConvert(toSave, collectionName).flatMap(toConvert -> { - AdaptibleEntity entity = operations.forEntity(toConvert, mongoConverter.getConversionService()); - entity.assertUpdateableIdIfNotSet(); - + AdaptibleEntity entity = operations.forEntityUpsert(toConvert, mongoConverter.getConversionService()); Document dbDoc = entity.toMappedDocument(writer).getDocument(); maybeEmitEvent(new BeforeSaveEvent(toConvert, dbDoc, collectionName)); @@ -2623,7 +2616,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati /** * Prepare the collection before any processing is done using it. This allows a convenient way to apply settings like - * withCodecRegistry() etc. Can be overridden in sub-classes. + * withCodecRegistry() etc. Can be overridden in subclasses. * * @param collection */ @@ -2647,9 +2640,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati /** * Prepare the WriteConcern before any processing is done using it. This allows a convenient way to apply custom - * settings in sub-classes.
- * The returned {@link WriteConcern} will be defaulted to {@link WriteConcern#ACKNOWLEDGED} when - * {@link WriteResultChecking} is set to {@link WriteResultChecking#EXCEPTION}. + * settings in subclasses. The returned {@link WriteConcern} will be defaulted to {@link WriteConcern#ACKNOWLEDGED} + * when {@link WriteResultChecking} is set to {@link WriteResultChecking#EXCEPTION}. * * @param mongoAction any WriteConcern already configured or {@literal null}. * @return The prepared WriteConcern or {@literal null}.