112

Is there an easy way to get the ID (ObjectID) of the last inserted document of a mongoDB instance using the Java driver?

Matt W
  • 6,078
  • 3
  • 32
  • 40

8 Answers8

201

I just realized you can do this:

BasicDBObject doc = new BasicDBObject( "name", "Matt" );
collection.insert( doc );
ObjectId id = (ObjectId)doc.get( "_id" );
Paolo Forgia
  • 6,572
  • 8
  • 46
  • 58
Matt W
  • 6,078
  • 3
  • 32
  • 40
  • 1
    Is it outdated? – Stu_Dent Oct 11 '20 at 13:14
  • @Stu_Dent No, but if your insertOne() has void return type, you are probably using the outdated mongodb driver. "mongo-java-driver"/"mongodb-driver" is legacy. You should probably be using " mongodb-driver-sync" https://mvnrepository.com/artifact/org.mongodb – dQw4w9WyXcQ Apr 27 '23 at 18:13
15

To avoid casting from Object to ObjectId, given a com.mongodb.client.MongoCollection collection and a org.bson.Document doc, you can do the following:

collection.insert(doc);
ObjectId id = doc.getObjectId("_id");
Jadiel de Armas
  • 8,405
  • 7
  • 46
  • 62
13

It's safe to do

doc.set("_id", new ObjectId())

if you look at driver code

if ( ensureID && id == null ){
    id = ObjectId.get();
    jo.put( "_id" , id );       
}

public static ObjectId get(){
    return new ObjectId();
}
zlob
  • 421
  • 8
  • 13
  • did you mean to say `it's save to do` or `it's safe to do`? – pd40 Oct 11 '12 at 00:07
  • 2
    For some reason, in MongoDB 2.2.2 (as opposed to earlier when I was on 2.2.0) and with the Java driver 2.10.1, the code in the answer doesn't work; after I upsert the object into the document, I can't seem to get its _id, even though MongoDB plainly auto-generates ObjectId's. However, your solution of manually creating an ObjectId does work, and thanks for this option! – Apophenia Overload Dec 04 '12 at 08:39
  • BasicDBObject doc = new BasicDBObject("_id", new ObjectId()); System.out.println("doc.id before: " + doc.get("_id")); new Mongo("localhost").getDB("test").getCollection("t").insert(doc); System.out.println("doc.id after: " + doc.get("_id")); this code work well for me, tested on new versions mongo 2.2.2, driver 2.10.1 – zlob Jan 16 '13 at 14:21
7

I do not know about the Java driver but for posterity, the getLastError command can be run to get the _id of a write, even an upsert (as of 1.5.4)

chx
  • 11,270
  • 7
  • 55
  • 129
4

After a document is inserted into the MongoDB collection, the successful insertion should update required fields (viz. _id). You may query the inserted object for the _id.

Ramesh
  • 189
  • 1
  • 2
0

In MongoTemplate.class has a method

protected <T> void doInsert(String collectionName, T objectToSave, MongoWriter<T> writer) {

    assertUpdateableIdIfNotSet(objectToSave);

    initializeVersionProperty(objectToSave);

    maybeEmitEvent(new BeforeConvertEvent<T>(objectToSave, collectionName));

    DBObject dbDoc = toDbObject(objectToSave, writer);

    maybeEmitEvent(new BeforeSaveEvent<T>(objectToSave, dbDoc, collectionName));
    Object id = insertDBObject(collectionName, dbDoc, objectToSave.getClass());

    populateIdIfNecessary(objectToSave, id);
    maybeEmitEvent(new AfterSaveEvent<T>(objectToSave, dbDoc, collectionName));
}

and the method will set id for us

protected void populateIdIfNecessary(Object savedObject, Object id) {

    if (id == null) {
        return;
    }

    if (savedObject instanceof BasicDBObject) {
        DBObject dbObject = (DBObject) savedObject;
        dbObject.put(ID_FIELD, id);
        return;
    }

    MongoPersistentProperty idProp = getIdPropertyFor(savedObject.getClass());

    if (idProp == null) {
        return;
    }

    ConversionService conversionService = mongoConverter.getConversionService();
    MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(savedObject.getClass());
    PersistentPropertyAccessor accessor = entity.getPropertyAccessor(savedObject);

    if (accessor.getProperty(idProp) != null) {
        return;
    }

    new ConvertingPropertyAccessor(accessor, conversionService).setProperty(idProp, id);
}

we can see if the entity is a sub-class of BasicDBObject,it will set a id for us.

Z.Billy
  • 1
  • 1
0

I think the answer to this is "No".

What you can do is provide your the _id yourself, either manually, or implement the CollectibleCodec mechanism (which is exactly what BasicBDDocument does). However all these solutions involve generating the ID clientside.

Having said that, I don't think there's any problem with generating the _id clientside.

Matthew
  • 10,361
  • 5
  • 42
  • 54
-2

This is insert operation:

DBCollection table1 = db.getCollection("Collection name");
BasicDBObject document = new BasicDBObject();
document.put("_id",value);      
document.put("Name", name);
table1.insert(document);

After insert u get last inserted id:

DBCollection tableDetails = db.getCollection("collection name");
BasicDBObject queryDetails = new BasicDBObject();
queryDetails.put("_id", value);
DBCursor cursorDetails =tableDetails.find(queryDetails);
DBObject oneDetails;
oneDetails=cursorDetails.next();        
String data=oneDetails.get("_id").toString();
System.out.println(data);

after getting value convert to inter type.

user27
  • 146
  • 1
  • 1
  • 8