Issue
I am working on this legacy application (7 years old). I have many methods that do the same thing that I am trying to upgrade to a newer MongoDB Java driver, but it won't compile.
@Override
public void saveOrUpdatePrinter(Document printer) {
printer.put(PRINTER_COLUMNS.updateDate,new Date());
MongoCollection<Document> collection = mongoTemplate.getCollection("PRINTERS");
printer.remove("_id");
Document query = new Document().append(PRINTER_COLUMNS.internal_id, printer.get(PRINTER_COLUMNS.internal_id));
WriteResult result = collection.update(query, printer, true, false);
logger.debug("saveOrUpdatePrinter updeded records: " + result.getN());
}//
The error is:
The method update(Document, Document, boolean, boolean) is undefined for the type MongoCollection<Document>
Why was this removed?
printer.remove("_id");
Also I would like to know how to do either update or save on the document in one go?
And what will be the proper way to update a single document in the new (MongoDB Java driver 4.7.0)?
Reading this code a little more seems like it was an attempt to do UPSERT operation (update or insert).
Solution
I will try to answer your questions.
Q : How to do either Update or Save on the Document in one go?
-> MongoDB's update
method updates the values in the existing document whereas the save
method replaces the existing document with the document passed. Nothing happens in one go.
update
method only updates which are specific fields which are modified by comparing the fields from the modified document with the original document whereas the save
method updates/replaces the values of all the fields of an original document by the taking values from the modified document and setting the values into the original document.
Q : What will be the proper way to update a single document in the new (Mongo Java driver 4.7.0)
-> You should be using updateOne(query, updates, options)
to update a single document on a MongoCollection object.
From updateOne docs :
The method accepts a filter that matches the document you want to update and an update statement that instructs the driver how to change the matching document. The updateOne() method only updates the first document that matches the filter.
To perform an update with the updateOne() method, you must pass a query filter and an update document. The query filter specifies the criteria for which document to perform the update on and the update document provides instructions on what changes to make to it.
You can optionally pass an instance of UpdateOptions to the updateOne() method in order to specify the method's behavior. For example, if you set the upsert field of the UpdateOptions object to true, the operation inserts a new document from the fields in both the query and update document if no documents match the query filter.
Q : Is it seems like it was an attempt to do UPSERT operation (Update or Insert) ?
-> Yes, it's an upsert operation.
Q : Why the code is trying to remove _id
from document ?
-> The update
method will update the document if the document was found by internal_id
. If the document was not found and also if there is no _id
field in the document, then the mongoshell will consider it as a new document and will invoke insert
method internally via the update
method to insert the document. For the insertion to happen, that's why it was removed from document.
Just update the code to this.
@Override
public void saveOrUpdatePrinter(Document printer) {
MongoCollection<Document> collection = mongoTemplate.getCollection("PRINTERS");
Document query = new Document().append(PRINTER_COLUMNS.internal_id, printer.get(PRINTER_COLUMNS.internal_id));
UpdateOptions options = new UpdateOptions().upsert(true);
printer.put(PRINTER_COLUMNS.updateDate,new Date());
UpdateResult result = collection.updateOne(query, printer, options);
logger.debug("saveOrUpdatePrinter updated records: " + result.getModifiedCount());
}
Answered By - Anish B.
Answer Checked By - Senaida (JavaFixing Volunteer)