Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update one document by _id (Invalid BSON field name _id)

Tags:

java

mongodb

I'm trying to update an document using updateOne method:

UpdateResult r = coll.updateOne(
    eq("_id", id),
    this.getMapper().mapToMongoDocumentEntry(entity)
);

Nevertheless, I'm getting an exception telling me:

Invalid BSON field name _id

mapToMongoDocumentEntity returns a Document like:

Document{
  _id=588b0d7108980f004323ca73,
  username=user,
  password=.---,
  cname=----,
  sname=,
  mail=mail,
  creation=Fri Jan 27 09:05:52      UTC 2017,
  validation=null
}

mapToMongoDocumentEntry code:

public Document mapToMongoDocumentEntry(User entity) {
    Document result = new Document();

    if (entity.getId() != null)
        result.put(UserEntityMongoDocumentMapper.FIELD_ID, new ObjectId(entity.getId()));

    result.put(UserEntityMongoDocumentMapper.FIELD_USER, entity.getUser());
    result.put(UserEntityMongoDocumentMapper.FIELD_PASSWORD, entity.getPasswd());
    result.put(UserEntityMongoDocumentMapper.FIELD_COMMONNAME, entity.getCname());
    result.put(UserEntityMongoDocumentMapper.FIELD_SURNAME, entity.getSname());
    result.put(UserEntityMongoDocumentMapper.FIELD_MAIL, entity.getMail());
    result.put(UserEntityMongoDocumentMapper.FIELD_CREATION, entity.getCreation());
    result.put(UserEntityMongoDocumentMapper.FIELD_VALIDATION, entity.getValidation());

    return result;
}

Any ideas?

like image 616
Jordi Avatar asked Jan 27 '17 09:01

Jordi


1 Answers

/**
 * Replace a document in the collection according to the specified arguments.
 *
 * @param filter      the query filter to apply the the replace operation
 * @param replacement the replacement document
 * @return the result of the replace one operation
 * @throws com.mongodb.MongoWriteException        if the write failed due some other failure specific to the replace command
 * @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
 * @throws com.mongodb.MongoException             if the write failed due some other failure
 * @mongodb.driver.manual tutorial/modify-documents/#replace-the-document Replace
 */
UpdateResult replaceOne(Bson filter, TDocument replacement);

should work well for you than the

/**
 * Update a single document in the collection according to the specified arguments.
 *
 * @param filter a document describing the query filter, which may not be null.
 * @param update a document describing the update, which may not be null. The update to apply must include only update operators.
 * @return the result of the update one operation
 * @throws com.mongodb.MongoWriteException        if the write failed due some other failure specific to the update command
 * @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
 * @throws com.mongodb.MongoException             if the write failed due some other failure
 * @mongodb.driver.manual tutorial/modify-documents/ Updates
 * @mongodb.driver.manual reference/operator/update/ Update Operators
 */
UpdateResult updateOne(Bson filter, Bson update);

The reasons I shared the documentation is to bring out two important clauses -

  1. updateOne readds - The update to apply must include only update operators and you its not a good idea to update the _id of an existing document rather replace the document with one if you are generating that as in your mapToMongoDocumentEntry method.
  2. Since the mapToMongoDocumentEntry returns the entire document and not just attributes the entire Document replacement is what you are actually seeking rather thatn updating fields of it.

Also, note that you can use both the above methods overloaded with an additional param UpdateOptions which can provide the support for document upsert, bypass etc.

like image 177
Naman Avatar answered Nov 08 '22 01:11

Naman