In case of bulkWrite(), I want array of _ids of successfully processed documents OR failed documents, along with reason for failure.
Following is the attempt I made. Suggest more easy approach if possible.
try {
collection.insertMany(documents, new InsertManyOptions().ordered(false));
} catch (DuplicateKeyException dke) {
LOGGER.error("{}", dke);
} catch (MongoBulkWriteException mbwe) {
List<BulkWriteError> errors = mbwe.getWriteErrors();
for (BulkWriteError error : errors) {
LOGGER.error("{}", error.getMessage());
}
} catch (Exception ex) {
LOGGER.error("{}", ex.getCause());
}
When I insert document with duplicate _ids, I supposed to get DuplicateKeyException as per javadoc, but I am getting MongoBulkWriteException.
I am using java 8 and mongodb 3.2.1 drivers
insertMany throws only the following exceptions:
MongoBulkWriteException - if there's an exception in the bulk write operation
MongoException - if the write failed due some other failure
However the exception carries the cause of it and in the case of a duplicated id will be something like:
insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.restaurants.$_id_ dup key: { : ObjectId('56c8ac3146235e4898bb696c') }
So since you have the information in the message you can extract with a regular expression the ids of the documents that failed in an array.
The code would be something like that (I am giving it inline in your code):
List<String>duplicateIds = new ArrayList<String>();
List<BulkWriteError> errors = mbwe.getWriteErrors();
for (BulkWriteError error : errors) {
LOGGER.error("{}", error.getMessage());
// extract from error.message the id of the duplicated document, (11000 is the duplicate id code)
if (error.getCode() == 11000) {
Matcher m = Pattern.compile("[0-9a-f]{24}")
.matcher(error.getMessage());
m.find();
duplicateIds.add(m.group());
}
}
// here the duplicateIds will hold all the found ids, you can print them in console for example:
System.out.println(duplicateIds.toString());
// and do whatever else you like with them
The above code will catch the duplicated Ids - if you want to make it to catch other errors it is easy to adapt it accordingly.
UPDATE:
If you want to use bulkWrite()
you can use exactly the same code since it throws the same exceptions (MongoBulkWrite, MongoException)
as insertMany()
, see BulkWrite()
If you want to update the code to catch other exceptions it is easily expandable: