How to upsert with mongodb-java-driver

If you are using mongo-java driver 3, following .updateOne() method with {upsert, true} flag works.

 void setLastIndex(MongoClient mongo, Long id, Long lastIndexValue) {

    Bson filter = Filters.eq("_id", id);

    Bson update =  new Document("$set",
                  new Document()
                        .append("lastIndex", lastIndexValue)
                        .append("created", new Date()));
    UpdateOptions options = new UpdateOptions().upsert(true);

    mongo.getDatabase(EventStreamApp.EVENTS_DB)
         .getCollection(EventCursor.name)
         .updateOne(filter, update, options);
  }

You cannot set _id if dbobject is just a document and does not contain an update operator eg: $set, $setOnInsert.

Just passing a document will replace the whole document meaning it doesn't set an _id a falls back to ObjectId

So your example works if you use an update operator eg:

db.getCollection(collection).update(
    new BasicDBObject("_id", "12"), 
    new BasicDBObject("$set", new BasicDBObject("Hi", "world")), true, false)