From 43db706c0d977075609d6c93eaa373296814b6d5 Mon Sep 17 00:00:00 2001
From: Parikshit Dutta
Date: Thu, 28 May 2020 21:55:26 +0530
Subject: [PATCH] Implemented BulkOperations API in MongoItemWriter
---
.../batch/item/data/MongoItemWriter.java | 37 ++++++++--
.../batch/item/data/MongoItemWriterTests.java | 73 ++++++++++++++-----
2 files changed, 83 insertions(+), 27 deletions(-)
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java
index d36414ab31..ed11a152d6 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/MongoItemWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2017 the original author or authors.
+ * Copyright 2012-2020 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,12 +19,22 @@
import java.util.ArrayList;
import java.util.List;
+import org.bson.Document;
+import org.bson.types.ObjectId;
+
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.InitializingBean;
+import org.springframework.data.mongodb.core.BulkOperations;
+import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
+import org.springframework.data.mongodb.core.FindAndReplaceOptions;
import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.convert.MongoConverter;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
@@ -42,6 +52,7 @@
*
*
* @author Michael Minella
+ * @author Parikshit Dutta
*
*/
public class MongoItemWriter implements ItemWriter, InitializingBean {
@@ -133,16 +144,28 @@ protected void doWrite(List extends T> items) {
}
}
else {
+ BulkOperations bulkOperations = null;
+
if(StringUtils.hasText(collection)) {
- for (Object object : items) {
- template.save(object, collection);
- }
+ bulkOperations = template.bulkOps(BulkMode.ORDERED, collection);
}
else {
- for (Object object : items) {
- template.save(object);
- }
+ bulkOperations = template.bulkOps(BulkMode.ORDERED, ClassUtils.getUserClass(items.get(0)));
+ }
+
+ for (Object object : items) {
+ Document document = new Document();
+
+ MongoConverter mongoConverter = template.getConverter();
+ mongoConverter.write(object, document);
+
+ Query query = new Query();
+ query.addCriteria(Criteria.where("_id").is((document.get("_id") != null)
+ ? document.get("_id") : new ObjectId()));
+
+ bulkOperations.replaceOne(query, document, new FindAndReplaceOptions().upsert());
}
+ bulkOperations.execute();
}
}
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java
index 05e5957e66..3f6e95fb5f 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/MongoItemWriterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2017 the original author or authors.
+ * Copyright 2013-2020 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,13 +19,17 @@
import java.util.Collections;
import java.util.List;
+import org.bson.Document;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
+import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.convert.MongoConverter;
+import org.springframework.data.mongodb.core.query.Query;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
@@ -33,22 +37,37 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verifyZeroInteractions;
+/**
+ * @author Michael Minella
+ * @author Parikshit Dutta
+ */
@SuppressWarnings("serial")
public class MongoItemWriterTests {
private MongoItemWriter