[JAVA-292] writeResult.getLastError().throwOnError() does not throw MongoException.DuplicateKey on duplicate key error Created: 08/Mar/11  Updated: 07/Apr/11  Resolved: 05/Apr/11

Status: Closed
Project: Java Driver
Component/s: None
Affects Version/s: 2.5
Fix Version/s: 2.5.3

Type: Bug Priority: Major - P3
Reporter: Martin Grotzke Assignee: Scott Hernandez (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

When an entity is inserted twice into a collection the returned WriteResult should throw a MongoException (DuplicateKey) from
writeResult.getLastError().throwOnError();

This is the case when the dbobject is inserted via collection.insert( dbo, WriteConcern.SAFE ), but not, when the dbobject is inserted via collection.insert( dbo ).
After writeResult.getLastError().throwOnError() the wrtieResult.err property is populated, but no exception has been thrown - which I had expected.

I tested this with the java driver from github master (commit e3c837a7 from 2011-03-04).

The following test case shows the described behaviour:

@Test
public void testDetectDuplicateKeyErrorWithDefaultWriteConcern() throws UnknownHostException, MongoException, InterruptedException {
final Mongo mongo = new Mongo( "localhost" );
final DBCollection collection = mongo.getDB( "foo" ).getCollection( "testcollection" );
final BasicDBObject dbo = new BasicDBObject();
collection.insert( dbo );
Thread.sleep( 2000 );
final WriteResult writeResult = collection.insert( dbo ); // when invoked with WriteConcern.SAFE the error is detected / exception thrown
try {
writeResult.getLastError().throwOnError();
// now the writeResult.err property is populated, but now exception is thrown
Assert.fail( "mongodb should complain about a duplicate key error index (MongoException.DuplicateKey), s.th. like the following:\n" +
"\"err\" : \"E11000 duplicate key error index: foo.testcollection.$id dup key: { : ObjectId('4d75fea23a75528813a7eedf') }\"" );
} catch( final Exception e )

{ // expected }

}



 Comments   
Comment by auto [ 04/Apr/11 ]

Author:

{u'login': u'scotthernandez', u'name': u'Scott Hernandez', u'email': u'scotthernandez@gmail.com'}

Message: JAVA-292 fixes WriteResult.getLastError().throwOnError()
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/66118a6a8dd646d44cf9fae9a0797f78354956d6

Comment by Martin Grotzke [ 09/Mar/11 ]

Sorry for the confusing issue report!

Regarding the documentation of the default WriteConcern: it would be great to have this mentioned in DBCollection.insert(DBObject) with a link to the clarification of (default) WriteConcern. Perhaps it's good to mention explicitely that "even" a duplicate key error is ignored with default WriteConcern and that insert(dbobject, WriteConcern.SAFE) should be used to recognize such errors?

Btw: is it "better" (in terms of performance) to use insert(dbobject, WriteConcern.SAFE) or to use insert(dbobject) + lastError.throwOnError? Does getLastError cause an additional server lookup?

Comment by Scott Hernandez (Inactive) [ 08/Mar/11 ]

Sorry, I misunderstood that throwOnError wasn't throwing... That is something I can look into.

As for the documentation, I do believe that default WriteConcern is discussed; I'll take a look specifically. Do you have a suggestion where you expected but didn't see it?

Comment by Martin Grotzke [ 08/Mar/11 ]

Ok, I just followed the path of the default WriteConcern in DBCollection.insert and AFAICS the Mongo.concern (WriteConcern.NORMAL) is used when nothing else is specified for a DB or DBCollection.
Is this documented somewhere? IMHO it would be good for users to get this information not too far from DBCollection.insert. For DBCollection.save it's documented that the default WriteConcern is used. For insert this information is IMHO more relevant, perhaps it would also be good to mention that duplicate keys are not detected with the default WriteConcern being NORMAL.

Another issue IMHO is that getLastError.throwOnError is expected not to throw an exception in the case above. Is there some documentation that I should read to get the mind set to follow this?
throwOnError tells me the following: "throws an exception containing the cmd name, in case the command failed" - and therefore I'd expect that this throws an exception in the case the command failed. Perhaps this documentation should contain more conditions regarding the WriteConcern used before?

Comment by Scott Hernandez (Inactive) [ 08/Mar/11 ]

If you don't use a WriteConcern.SAFE/STRICT or greater then the exception is not thrown since the error was not detected during the write operation; that is expected behavior. When you later call to check the error, then the error is returned but no exception is thrown – that is also expected behavior.

Comment by Martin Grotzke [ 08/Mar/11 ]

I just realized that the collection.insert should already throw the MongoException.DuplicateKey. So the title is wrong, and the collection.insert in the test would have to be pulled into the try/catch.

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