diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java index 4727c0b8db..23e14f51e2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java @@ -51,6 +51,7 @@ import com.mongodb.ReadPreference; import com.mongodb.client.ClientSession; import com.mongodb.client.MongoCollection; +import com.mongodb.client.model.InsertManyOptions; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; @@ -71,6 +72,7 @@ * @author Thomas Darimont * @author Maninder Singh * @author Mark Paluch + * @author Tomasz Forys */ public interface MongoOperations extends FluentMongoOperations { @@ -1371,6 +1373,19 @@ default long exactCount(Query query, String collectionName) { Collection insert(Collection batchToSave, Class entityClass); /** + * Insert a Collection of objects into a collection in a single batch write to the database with additional + * insert options. + * + * @param batchToSave the batch of objects to save. Must not be {@literal null}. + * @param entityClass class that determines the collection to use. Must not be {@literal null}. + * @param options options for insert many operation. Must not be {@literal null}. + * @return the inserted objects that. + * @throws org.springframework.data.mapping.MappingException if the target collection name cannot be + * {@link #getCollectionName(Class) derived} from the given type. + */ + Collection insert(Collection batchToSave, Class entityClass, InsertManyOptions options); + + /** * Insert a batch of objects into the specified collection in a single batch write to the database. * * @param batchToSave the list of objects to save. Must not be {@literal null}. @@ -1379,6 +1394,17 @@ default long exactCount(Query query, String collectionName) { */ Collection insert(Collection batchToSave, String collectionName); + /** + * Insert a batch of objects into the specified collection in a single batch write to the database with additional + * insert options. + * + * @param batchToSave the list of objects to save. Must not be {@literal null}. + * @param collectionName name of the collection to store the object in. Must not be {@literal null}. + * @param options options for insert many operation. Must not be {@literal null}. + * @return the inserted objects that. + */ + Collection insert(Collection batchToSave, String collectionName, InsertManyOptions options); + /** * Insert a mixed Collection of objects into a database collection determining the collection name to use based on the * class. @@ -1390,6 +1416,18 @@ default long exactCount(Query query, String collectionName) { */ Collection insertAll(Collection objectsToSave); + /** + * Insert a mixed Collection of objects into a database collection determining the collection name to use based on the + * class with additional insert options. + * + * @param objectsToSave the list of objects to save. Must not be {@literal null}. + * @param options options for insert many operation. Must not be {@literal null}. + * @return the inserted objects. + * @throws org.springframework.data.mapping.MappingException if the target collection name cannot be + * {@link #getCollectionName(Class) derived} for the given objects. + */ + Collection insertAll(Collection objectsToSave, InsertManyOptions options); + /** * Save the object to the collection for the entity type of the object to save. This will perform an insert if the * object is not already present, that is an 'upsert'.
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 3738a48df0..6902a0bde9 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 @@ -140,6 +140,7 @@ * @author Anton Barkan * @author Bartłomiej Mazur * @author Michael Krog + * @author Tomasz Forys */ public class MongoTemplate implements MongoOperations, ApplicationContextAware, IndexOperationsProvider { @@ -1234,34 +1235,44 @@ protected T doInsert(String collectionName, T objectToSave, MongoWriter w } @Override - @SuppressWarnings("unchecked") public Collection insert(Collection batchToSave, Class entityClass) { + return insert(batchToSave, getCollectionName(entityClass)); + } - Assert.notNull(batchToSave, "BatchToSave must not be null"); + @Override + public Collection insert(Collection batchToSave, Class entityClass, InsertManyOptions options) { + return insert(batchToSave, getCollectionName(entityClass), options); + } - return (Collection) doInsertBatch(getCollectionName(entityClass), batchToSave, this.mongoConverter); + @Override + public Collection insert(Collection batchToSave, String collectionName) { + return insert(batchToSave, collectionName, new InsertManyOptions()); } @Override @SuppressWarnings("unchecked") - public Collection insert(Collection batchToSave, String collectionName) { + public Collection insert(Collection batchToSave, String collectionName, InsertManyOptions options) { Assert.notNull(batchToSave, "BatchToSave must not be null"); Assert.notNull(collectionName, "CollectionName must not be null"); - return (Collection) doInsertBatch(collectionName, batchToSave, this.mongoConverter); + return (Collection) doInsertBatch(collectionName, batchToSave, this.mongoConverter, options); } @Override - @SuppressWarnings("unchecked") public Collection insertAll(Collection objectsToSave) { + return insertAll(objectsToSave, new InsertManyOptions()); + } + + @Override + @SuppressWarnings("unchecked") + public Collection insertAll(Collection objectsToSave, InsertManyOptions options) { Assert.notNull(objectsToSave, "ObjectsToSave must not be null"); - return (Collection) doInsertAll(objectsToSave, this.mongoConverter); + return (Collection) doInsertAll(objectsToSave, this.mongoConverter, options); } - @SuppressWarnings("unchecked") - protected Collection doInsertAll(Collection listToSave, MongoWriter writer) { + protected Collection doInsertAll(Collection listToSave, MongoWriter writer, InsertManyOptions options) { Map> elementsByCollection = new HashMap<>(); List savedObjects = new ArrayList<>(listToSave.size()); @@ -1273,27 +1284,22 @@ protected Collection doInsertAll(Collection listToSave, Mong } String collection = getCollectionName(ClassUtils.getUserClass(element)); - List collectionElements = elementsByCollection.get(collection); - - if (null == collectionElements) { - collectionElements = new ArrayList<>(); - elementsByCollection.put(collection, collectionElements); - } - + List collectionElements = elementsByCollection.computeIfAbsent(collection, k -> new ArrayList<>()); collectionElements.add(element); } for (Map.Entry> entry : elementsByCollection.entrySet()) { - savedObjects.addAll((Collection) doInsertBatch(entry.getKey(), entry.getValue(), this.mongoConverter)); + savedObjects.addAll(doInsertBatch(entry.getKey(), entry.getValue(), writer, options)); } return savedObjects; } protected Collection doInsertBatch(String collectionName, Collection batchToSave, - MongoWriter writer) { + MongoWriter writer, InsertManyOptions options) { Assert.notNull(writer, "MongoWriter must not be null"); + Assert.notNull(options, "InsertManyOptions must not be null"); List documentList = new ArrayList<>(batchToSave.size()); List initializedBatchToSave = new ArrayList<>(batchToSave.size()); @@ -1315,7 +1321,7 @@ protected Collection doInsertBatch(String collectionName, Collection ids = insertDocumentList(collectionName, documentList); + List ids = insertDocumentList(collectionName, documentList, options); List savedObjects = new ArrayList<>(documentList.size()); int i = 0; @@ -1445,7 +1451,7 @@ protected Object insertDocument(String collectionName, Document document, Class< }); } - protected List insertDocumentList(String collectionName, List documents) { + protected List insertDocumentList(String collectionName, List documents, InsertManyOptions options) { if (documents.isEmpty()) { return Collections.emptyList(); @@ -1462,9 +1468,9 @@ protected List insertDocumentList(String collectionName, List WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction); if (writeConcernToUse == null) { - collection.insertMany(documents); + collection.insertMany(documents, options); } else { - collection.withWriteConcern(writeConcernToUse).insertMany(documents); + collection.withWriteConcern(writeConcernToUse).insertMany(documents, options); } return null; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java index 323ca9dd95..8f511262a2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java @@ -50,6 +50,7 @@ import com.mongodb.ClientSessionOptions; import com.mongodb.ReadPreference; +import com.mongodb.client.model.InsertManyOptions; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; import com.mongodb.reactivestreams.client.ClientSession; @@ -68,6 +69,7 @@ * @author Mark Paluch * @author Christoph Strobl * @author Mathieu Ouellet + * @author Tomasz Forys * @since 2.0 * @see Flux * @see Mono @@ -1146,6 +1148,16 @@ default Mono exactCount(Query query, String collectionName) { */ Flux insert(Collection batchToSave, String collectionName); + /** + * Insert a batch of objects into the specified collection in a single batch write to the database with additional + * insert options. + * + * @param batchToSave the list of objects to save. Must not be {@literal null}. + * @param collectionName name of the collection to store the object in. Must not be {@literal null}. + * @param options options for insert many operation. Must not be {@literal null}. + * @return the inserted objects. + */ + Flux insert(Collection batchToSave, String collectionName, InsertManyOptions options); /** * Insert a mixed Collection of objects into a database collection determining the collection name to use based on the * class. @@ -1157,6 +1169,52 @@ default Mono exactCount(Query query, String collectionName) { */ Flux insertAll(Collection objectsToSave); + /** + * Insert a mixed Collection of objects into a database collection determining the collection name to use based on the + * class with additional insert options. + * + * @param objectsToSave the list of objects to save. Must not be {@literal null}. + * @param options options for insert many operation. Must not be {@literal null}. + * @return the saved objects. + * @throws org.springframework.data.mapping.MappingException if the target collection name cannot be + * {@link #getCollectionName(Class) derived} for the given objects. + */ + Flux insertAll(Collection objectsToSave, InsertManyOptions options); + + /** + * Insert a mixed Collection of objects into a database collection determining the collection name to use based on the + * class with additional insert options. + * + * @param objectsToSave the publisher which provides objects to save. Must not be {@literal null}. + * @param options options for insert many operation. Must not be {@literal null}. + * @return the inserted objects. + */ + Flux insertAll(Mono> objectsToSave, InsertManyOptions options); + + /** + * Insert a Collection of objects into a collection in a single batch write to the database with additional + * insert options. + * + * @param batchToSave the publisher which provides objects to save. Must not be {@literal null}. + * @param entityClass class that determines the collection to use. Must not be {@literal null}. + * @param options options for insert many operation. Must not be {@literal null}. + * @return the inserted objects. + * @throws org.springframework.data.mapping.MappingException if the target collection name cannot be + * {@link #getCollectionName(Class) derived} for the type. + */ + Flux insertAll(Mono> batchToSave, Class entityClass, InsertManyOptions options); + + /** + * Insert objects into the specified collection in a single batch write to the database with additional insert + * options. + * + * @param batchToSave the publisher which provides objects to save. Must not be {@literal null}. + * @param collectionName name of the collection to store the object in. Must not be {@literal null}. + * @param options options for insert many operation. Must not be {@literal null}. + * @return the inserted objects. + */ + Flux insertAll(Mono> batchToSave, String collectionName, InsertManyOptions options); + /** * Insert the object into the collection for the entity type of the object to save.
* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}.
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 5e33adb753..b2941141ee 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 @@ -156,6 +156,7 @@ * @author Roman Puchkovskiy * @author Mathieu Ouellet * @author Yadhukrishna S Pai + * @author Tomasz Forys * @since 2.0 */ public class ReactiveMongoTemplate implements ReactiveMongoOperations, ApplicationContextAware { @@ -1210,12 +1211,22 @@ public Flux insertAll(Mono> batchToSave return insertAll(batchToSave, getCollectionName(entityClass)); } + @Override + public Flux insertAll(Mono> batchToSave, Class entityClass, InsertManyOptions options) { + return insertAll(batchToSave, getCollectionName(entityClass), options); + } + @Override public Flux insertAll(Mono> batchToSave, String collectionName) { + return insertAll(batchToSave, collectionName, new InsertManyOptions()); + } + + @Override + public Flux insertAll(Mono> batchToSave, String collectionName, InsertManyOptions options) { Assert.notNull(batchToSave, "Batch to insert must not be null"); - return Flux.from(batchToSave).flatMap(collection -> insert(collection, collectionName)); + return Flux.from(batchToSave).flatMap(collection -> insert(collection, collectionName, options)); } @Override @@ -1268,17 +1279,32 @@ protected Mono doInsert(String collectionName, T objectToSave, MongoWrite @Override public Flux insert(Collection batchToSave, Class entityClass) { - return doInsertBatch(getCollectionName(entityClass), batchToSave, this.mongoConverter); + return insert(batchToSave, getCollectionName(entityClass)); } @Override public Flux insert(Collection batchToSave, String collectionName) { - return doInsertBatch(collectionName, batchToSave, this.mongoConverter); + return insert(batchToSave, collectionName, new InsertManyOptions()); + } + + @Override + public Flux insert(Collection batchToSave, String collectionName, InsertManyOptions options) { + return doInsertBatch(collectionName, batchToSave, this.mongoConverter, options); + } + + @Override + public Flux insertAll(Collection objectsToSave, InsertManyOptions options) { + return doInsertAll(objectsToSave, this.mongoConverter, options); + } + + @Override + public Flux insertAll(Mono> objectsToSave, InsertManyOptions options) { + return Flux.from(objectsToSave).flatMap(collection -> insertAll(collection, options)); } @Override public Flux insertAll(Collection objectsToSave) { - return doInsertAll(objectsToSave, this.mongoConverter); + return doInsertAll(objectsToSave, this.mongoConverter, new InsertManyOptions()); } @Override @@ -1286,7 +1312,7 @@ public Flux insertAll(Mono> objectsToSa return Flux.from(objectsToSave).flatMap(this::insertAll); } - protected Flux doInsertAll(Collection listToSave, MongoWriter writer) { + protected Flux doInsertAll(Collection listToSave, MongoWriter writer, InsertManyOptions insertManyOptions) { Map> elementsByCollection = new HashMap<>(); @@ -1299,13 +1325,14 @@ protected Flux doInsertAll(Collection listToSave, MongoWrite }); return Flux.fromIterable(elementsByCollection.keySet()) - .flatMap(collectionName -> doInsertBatch(collectionName, elementsByCollection.get(collectionName), writer)); + .flatMap(collectionName -> doInsertBatch(collectionName, elementsByCollection.get(collectionName), writer, insertManyOptions)); } protected Flux doInsertBatch(String collectionName, Collection batchToSave, - MongoWriter writer) { + MongoWriter writer, InsertManyOptions options) { Assert.notNull(writer, "MongoWriter must not be null"); + Assert.notNull(options, "InsertManyOptions must not be null"); Mono, Document>>> prepareDocuments = Flux.fromIterable(batchToSave) .flatMap(uninitialized -> { @@ -1331,7 +1358,7 @@ protected Flux doInsertBatch(String collectionName, Collection documents = tuples.stream().map(Tuple2::getT2).collect(Collectors.toList()); - return insertDocumentList(collectionName, documents).thenMany(Flux.fromIterable(tuples)); + return insertDocumentList(collectionName, documents, options).thenMany(Flux.fromIterable(tuples)); }); return insertDocuments.flatMap(tuple -> { @@ -1468,7 +1495,7 @@ protected Mono insertDocument(String collectionName, Document dbDoc, Cla return Flux.from(execute).last().map(success -> document.getId()); } - protected Flux insertDocumentList(String collectionName, List dbDocList) { + protected Flux insertDocumentList(String collectionName, List dbDocList, InsertManyOptions options) { if (dbDocList.isEmpty()) { return Flux.empty(); @@ -1489,7 +1516,7 @@ protected Flux insertDocumentList(String collectionName, List { 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 30978bce96..1f6d56d53b 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 @@ -106,6 +106,7 @@ import com.mongodb.client.MongoCursor; import com.mongodb.client.model.Filters; import com.mongodb.client.model.IndexOptions; +import com.mongodb.client.model.InsertManyOptions; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; @@ -122,6 +123,7 @@ * @author Mark Paluch * @author Laszlo Csontos * @author duozhilin + * @author Tomasz Forys */ @ExtendWith(MongoClientExtension.class) public class MongoTemplateTests { @@ -287,16 +289,56 @@ public void rejectsDuplicateIdInInsertAll() { MongoTemplate template = new MongoTemplate(factory); template.setWriteResultChecking(WriteResultChecking.EXCEPTION); - ObjectId id = new ObjectId(); - Person person = new Person(id, "Amol"); - person.setAge(28); + ObjectId duplicatedId = new ObjectId(); + Person first = new Person(duplicatedId, "Amol"); + first.setAge(28); + Person second = new Person(duplicatedId, "Bmol"); + first.setAge(29); + Person uniquePerson = new Person("Cmol", 30); + + assertThatExceptionOfType(DataIntegrityViolationException.class) + .isThrownBy(() -> template.insertAll(Arrays.asList(first, second, uniquePerson))) + .withMessageContaining("E11000 duplicate key error"); - List records = new ArrayList<>(); - records.add(person); - records.add(person); + Query query = new Query(where("firstName").is(uniquePerson.getFirstName())); + Person found = template.findOne(query, Person.class); + assertThat(found).isNull(); + } + + @Test + public void storeCorrectObjectsOnInsertAllWithInsertManyOptionsAndUniqueViolation() { + + MongoTemplate template = new MongoTemplate(factory); + template.setWriteResultChecking(WriteResultChecking.EXCEPTION); - assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(() -> template.insertAll(records)) + ObjectId duplicatedId = new ObjectId(); + Person first = new Person(duplicatedId, "Amol"); + first.setAge(28); + Person second = new Person(duplicatedId, "Bmol"); + first.setAge(29); + Person uniquePerson = new Person("Cmol", 30); + + assertThatExceptionOfType(DataIntegrityViolationException.class) + .isThrownBy(() -> template.insertAll(Arrays.asList(first, second, uniquePerson), new InsertManyOptions().ordered(false))) .withMessageContaining("E11000 duplicate key error"); + + Query query = new Query(where("firstName").is(uniquePerson.getFirstName())); + Person found = template.findOne(query, Person.class); + assertThat(found).isNotNull(); + assertThat(found.getAge()).isEqualTo(30); + } + + @Test + void testNullInsertManyOptionsValidation() { + + MongoTemplate template = new MongoTemplate(factory); + template.setWriteResultChecking(WriteResultChecking.EXCEPTION); + + Person person = new Person("Amol", 30); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> template.insertAll(Arrays.asList(person), null)) + .withMessageContaining("InsertManyOptions must not be null"); } @Test // DATAMONGO-1687 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java index 850797880d..1efe1a34cf 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java @@ -142,6 +142,7 @@ * @author Michael J. Simons * @author Roman Puchkovskiy * @author Yadhukrishna S Pai + * @author Tomasz Forys */ @MockitoSettings(strictness = Strictness.LENIENT) public class MongoTemplateUnitTests extends MongoOperationsUnitTests { @@ -2186,7 +2187,8 @@ void insertAllShouldInvokeAfterSaveCallbacks() { Collection saved = template.insertAll(Arrays.asList(entity1, entity2)); verify(afterSaveCallback, times(2)).onAfterSave(any(), any(), anyString()); - assertThat(saved.iterator().next().getId()).isEqualTo("after-save"); + assertThat(saved).hasSize(2); + assertThat(saved).map(e -> e.getId()).containsExactly("after-save", "after-save"); } @Test // DATAMONGO-2479 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 6ca3808c9a..a2144cdfc2 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 @@ -86,6 +86,7 @@ import org.springframework.data.mongodb.test.util.ReactiveMongoTestTemplate; import com.mongodb.WriteConcern; +import com.mongodb.client.model.InsertManyOptions; import com.mongodb.reactivestreams.client.MongoClient; /** @@ -93,6 +94,7 @@ * * @author Mark Paluch * @author Christoph Strobl + * @author Tomasz Forys */ @ExtendWith({ MongoClientExtension.class, MongoServerCondition.class }) public class ReactiveMongoTemplateTests { @@ -537,13 +539,58 @@ void rejectsDuplicateIdInInsertAll() { ReactiveMongoTemplate template = new ReactiveMongoTemplate(factory); template.setWriteResultChecking(WriteResultChecking.EXCEPTION); - ObjectId id = new ObjectId(); - Person person = new Person(id, "Amol"); - person.setAge(28); + ObjectId duplicatedId = new ObjectId(); + Person first = new Person(duplicatedId, "Amol"); + first.setAge(28); + Person second = new Person(duplicatedId, "Bmol"); + first.setAge(29); + Person uniquePerson = new Person("Cmol", 30); + + template.insertAll(Arrays.asList(first, second, uniquePerson)) // + .as(StepVerifier::create) // + .verifyError(DataIntegrityViolationException.class); + + Query query = new Query(where("firstName").is(uniquePerson.getFirstName())); + Person found = template.findOne(query, Person.class).block(); + assertThat(found).isNull(); + } + + @Test + void storeCorrectObjectsOnInsertAllWithInsertManyOptionsAndUniqueViolation() { + + ReactiveMongoTemplate template = new ReactiveMongoTemplate(factory); + template.setWriteResultChecking(WriteResultChecking.EXCEPTION); + + ObjectId duplicatedId = new ObjectId(); + Person first = new Person(duplicatedId, "Amol"); + first.setAge(28); + Person second = new Person(duplicatedId, "Bmol"); + first.setAge(29); + Person uniquePerson = new Person("Cmol", 30); - template.insertAll(Arrays.asList(person, person)) // + template.insertAll(Arrays.asList(first, second, uniquePerson), new InsertManyOptions().ordered(false)) // .as(StepVerifier::create) // .verifyError(DataIntegrityViolationException.class); + + Query query = new Query(where("firstName").is(uniquePerson.getFirstName())); + Person found = template.findOne(query, Person.class).block(); + assertThat(found).isNotNull(); + assertThat(found.getAge()).isEqualTo(30); + } + + @Test + void testNullInsertManyOptionsValidation() { + + ReactiveMongoTemplate template = new ReactiveMongoTemplate(factory); + template.setWriteResultChecking(WriteResultChecking.EXCEPTION); + + Person person = new Person("Amol", 30); + + template.insertAll(Arrays.asList(person), null) // + .as(StepVerifier::create) // + .verifyErrorSatisfies(error -> + assertThat(error).isInstanceOf(IllegalArgumentException.class) + .hasMessage("InsertManyOptions must not be null")); } @Test // DATAMONGO-1444 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java index df1bb84466..b52af80033 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java @@ -131,6 +131,7 @@ * @author Roman Puchkovskiy * @author Mathieu Ouellet * @author Yadhukrishna S Pai + * @author Tomasz Forys */ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) @@ -1372,7 +1373,7 @@ void insertAllShouldInvokeAfterSaveCallbacks() { entity1.id = "2"; entity1.firstname = "luke"; - when(collection.insertMany(anyList())).then(invocation -> { + when(collection.insertMany(anyList(), any())).then(invocation -> { List list = invocation.getArgument(0); return Flux.fromIterable(list).map(i -> mock(InsertManyResult.class)); });