[JAVA-1788] Insert method should return a result instead of void Created: 30/Apr/15  Updated: 11/Nov/21  Resolved: 19/Nov/19

Status: Closed
Project: Java Driver
Component/s: API
Affects Version/s: 3.0.0
Fix Version/s: 4.0.0

Type: New Feature Priority: Minor - P4
Reporter: Junilu Lacar Assignee: Ross Lawley
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by JAVA-2550 Add "inserted Ids" to BulkWriteResult Closed
Related
is related to JAVA-4403 Trying to bulk load documents with co... Closed
Backwards Compatibility: Major Change

 Description   

In the Java driver, MongoCollection.insertOne seems to behave inconsistently with insert behavior in Mongo Shell and the pyMongo insert_one method. The Java method is void whereas the collection.insert(Document) method in Mongo Shell returns the result as an object (typeof reports 'object'). In pyMongo, insert_one returns a pymongo.results.InsertOneResult object.

Furthermore, the Java Driver mutates the parameter passed to insertOne() by adding the "_id" key. This does not happen to the document passed to insert() in the Mongo Shell and I don't think it happens to the document that is passed to insert_one in pyMongo either.

At any rate, the behavior of the Java driver with respect to the results of insertOne violates the Principle of Least Astonishment, IMO, and at the very least, the JavaDocs should be updated to at least warn developers of this inconsistent behavior.



 Comments   
Comment by Githook User [ 15/Jan/20 ]

Author:

{'name': 'Ross Lawley', 'username': 'rozza', 'email': 'ross.lawley@gmail.com'}

Message: Insertions now return a result

Added InsertOneResult and InsertManyResult to insert operations

JAVA-1788
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/85caac9ec625d101e7d678276027ed8c063f66a6

Comment by Ross Lawley [ 11/Nov/19 ]

PR: https://github.com/rozza/mongo-java-driver/pull/335

Comment by Ross Lawley [ 01/May/15 ]

Just a note about Casbah (the scala driver) it wraps the 2.x version of the driver and as such follows the conventions of DBCollection and underneath uses the Java driver, so mutates the java document.

We are writing a new Scala driver which will support both mutable and immutable documents and will in general follow the API of the Java driver 3.0. How it will handle immutable documents that don't have an _id hasn't been formalised yet.

Comment by Junilu Lacar [ 01/May/15 ]

Another inconsistency with the write methods is the return value. The pymongo driver returns a pymongo.results.InsertOneResult from insert_one, the Java driver MongoCollection.insertOne is declared as void, and the Scala driver MongoCollection.insert returns a TypeImports.WriteResult which is actually the closest thing to what the Shell does, which returns a WriteResult object as well.

> res = db.fubar.insert(doc)
WriteResult({ "nInserted" : 1 })
 
> typeof res
object

Since Java and Scala both run on the JVM, it seems reasonable to expect the drivers for these languages to be more closely aligned with each other and perhaps even interchangeable. (shrug)

Comment by Junilu Lacar [ 01/May/15 ]

Ok, thanks. I can imagine the kind of conversations that may have transpired that led to the decision to have the insert operations in the drivers mutate the document parameter and I can see how this behavior can be convenient in certain use cases but it still doesn't seem right that this is inconsistent with how things happen in the Shell.

Have there been no complaints about this kind of behavior from developers who prefer a more functional style of programming? I just had a quick look at the Scala driver documentation and it looks like the insert method does mutate its parameter as well. I imagine that this would definitely be a surprise for Scala programmers who are trying to learn how to use MongoDB. Or maybe it's just me; I don't know.

This is what I tried in the Mongo shell:

> use test
switched to db test
 
> doc = {a:5, b:5, c:5555}
{ "a" : 5, "b" : 5, "c" : 5555 }
 
> db.fubar.insert(doc)
WriteResult({ "nInserted" : 1 })
 
> doc
{ "a" : 5, "b" : 5, "c" : 5555 }
 
> db.fubar.insert(doc)
WriteResult({ "nInserted" : 1 })
 
> doc
{ "a" : 5, "b" : 5, "c" : 5555 }
 
> db.fubar.find({a:5})
{ "_id" : ObjectId("5542234eb8aa3c1b4dd7b89b"), "a" : 5, "b" : 5, "c" : 5555 }
{ "_id" : ObjectId("55422366b8aa3c1b4dd7b89c"), "a" : 5, "b" : 5, "c" : 5555 }

These results seem perfectly reasonable to me and I think it's unfortunate that the drivers deviate from this. So documents can be mutated on write even with the Node.js driver? That's kind of a big gotcha there, considering that Node.js and the Shell are both Javascript.

Comment by Jeffrey Yemin [ 30/Apr/15 ]

It's also consistent with the behavior of DBCollection.insert(), which was our biggest concern. The documentation currently states:

Inserts the provided document. If the document is missing an identifier, the driver should generate one.

That "should" should probably be a "will". And insertMany/bulkWrite don't mention this behavior at all, so we should update the Javadoc for those as well. Thanks for bringing this to our attention.

Comment by Bernie Hackett [ 30/Apr/15 ]

...and I don't think it happens to the document that is passed to insert_one in pyMongo either.

Actually, PyMongo does mutate the document for insert, and always has (and insert_one, insert_many, bulk_write, etc). I believe most of our drivers do this.

Generated at Thu Feb 08 08:55:29 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.