MongoTemplate upsert - easy way to make Update from pojo (which user has editted)?

spring boot mongodb update document
spring data mongodb update array
mongotemplate aggregate
mongotemplate executecommand
mongotemplate count
mongooperations vs mongotemplate
spring data mongodb update subdocument
update.from document example

Here is a simple pojo:

public class Description {
    private String code;
    private String name;
    private String norwegian;
    private String english;
}

And please see the following code to apply an upsert to MongoDb via spring MongoTemplate:

Query query = new Query(Criteria.where("code").is(description.getCode()));
Update update = new Update().set("name", description.getName()).set("norwegian", description.getNorwegian()).set("english", description.getEnglish());
mongoTemplate.upsert(query, update, "descriptions");

The line to generate the Update object specifies every field of the Item class manually.

But if my Item object changes then my Dao layer breaks.

So is there a way to avoid doing this, so that all fields from my Item class are applied automatically to the update?

E.g.

Update update = new Update().fromObject(item);

Note that my pojo does not extend DBObject.

I ran into the same problem. In het current Spring Data MongoDB version no such thing is available. You have to update the seperate fields by hand.

However it is possible with another framework: Morphia.

This framework has a wrapper for DAO functionality: https://github.com/mongodb/morphia/wiki/DAOSupport

You can use the DAO API to do things like this:

SomePojo pojo = daoInstance.findOne("some-field", "some-value");
pojo.setAProperty("changing this property");
daoInstance.save(pojo);

In Spring data – MongoDB, you can use following methods to update documents. save – Update the whole object, if “_id” is present, perform an update, else insert it. Find the document, modify and update it with save() method. 21); mongoOperation.upsert(query, update, User.class); User userTest5  Meta user. Network profile 544. reputation. 1. 7. 16. Vivek Sethi. 2 MongoTemplate upsert - easy way to make Update from pojo (which user has editted)?

I found a pretty good solution for this question

//make a new description here
Description d = new Description();
d.setCode("no");
d.setName("norwegian");
d.setNorwegian("norwegian");
d.setEnglish("english");

//build query
Query query = new Query(Criteria.where("code").is(description.getCode()));

//build update
DBObject dbDoc = new BasicDBObject();
mongoTemplate.getConverter().write(d, dbDoc); //it is the one spring use for convertions.
Update update = Update.fromDBObject(dbDoc);

//run it!
mongoTemplate.upsert(query, update, "descriptions");

Plz note that Update.fromDBObject return an update object with all fields in dbDoc. If you just want to update non-null fields, you should code a new method to exclude null fields.

For example, the front-end post a doc like below:

//make a new description here
Description d = new Description();
d.setCode("no");
d.setEnglish("norwegian");

We only need to update the field 'language':

//return Update object
public static Update fromDBObjectExcludeNullFields(DBObject object) {
    Update update = new Update();       
    for (String key : object.keySet()) {
        Object value = object.get(key);
        if(value!=null){
            update.set(key, value);
        }
    }
    return update;
}

//build udpate
Update update = fromDBObjectExcludeNullFields(dbDoc);

Source: MongoTemplate upsert - easy way to make Update from pojo (which user has editted)? public UserDto UpdateDto(ObjectId id, User users) { Document  mongotemplate. Score 1. Posts 1. View all tags → 1 MongoTemplate upsert - easy way to make Update from pojo user contributions licensed under cc by-sa 4.0

The solution for a new spring-data-mongodb version 2.X.X.

The API has evolved, since 2.X.X version there is:

Update.fromDocument(org.bson.Document object, String... exclude)

instead of (1.X.X):

Update.fromDBObject(com.mongodb.DBObject object, String... exclude)

The full solution:

//make a new description here
Description d = new Description();
d.setCode("no");
d.setName("norwegian");
d.setNorwegian("norwegian");
d.setEnglish("english");
Query query = new Query(Criteria.where("code").is(description.getCode()));

Document doc = new Document(); // org.bson.Document
mongoTemplate.getConverter().write(item, doc);
Update update = Update.fromDocument(doc);

mongoTemplate.upsert(query, update, "descriptions");

It works!

MongoTemplate upsert - easy way to make Update from pojo (which user has editted)?. DB db = mongoTemplate.getDb(); DBCollection collection = db. mongotemplate. Score 0. Posts 1. java. Score 0. 0 MongoTemplate upsert - easy way to make Update from pojo user contributions licensed under cc by-sa 4.0 with

you can use save : (if non exist = insert else = upsert)

save(Object objectToSave, String collectionName)

read : javadoc

Create a collection with a name based on the provided entity class using the options. com.mongodb.client Performs an upsert. To update an existing object use the save method. Specified entityClass - class of the pojo to be operated on. PouchDB Upsert. A tiny plugin for PouchDB that provides two convenience methods: upsert() - update a document, or insert a new one if it doesn't exist (upsert). Will keep retrying (forever) if it gets 409 conflicts. putIfNotExists() - create a new document if it doesn't exist. Does nothing if it already exists.

This is what I am doing for the time being. Not so much elegant way to do it, but it does save a precious DB call:

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;

/**
 * Perform an upsert operation to update ALL FIELDS in an object using native mongo driver's methods
 * since mongoTemplate's upsert method doesn't allow it
 * @param upsertQuery
 * @param object
 * @param collectionName
 */
private void performUpsert(Query upsertQuery, Object object, String collectionName){

    ObjectMapper mapper = new ObjectMapper();

    try {
        String jsonStr = mapper.writeValueAsString(object);
        DB db = mongoTemplate.getDb();
        DBCollection collection = db.getCollection(collectionName);
        DBObject query = upsertQuery.getQueryObject();
        DBObject update = new BasicDBObject("$set", JSON.parse(jsonStr));
        collection.update(query, update, true, false);
    } catch (IOException e) {
        LOGGER.error("Unable to persist the metrics in DB. Error while parsing object: {}", e);
    }
}

Includes integrated object mapping between documents and POJOs. An easy way to bootstrap setting up a working environment is to create a Spring based While you can use Spring's traditional <beans/> XML namespace to register an MongoTemplate provides a simple way for you to save, update, and delete your  In Spring data – MongoDB, you can use following methods to update documents. save – Update the whole object, if “_id” is present, perform an update, else insert it.

Have a look at how to store, index and search geospatial data with MongoDB Let's start with the simple XML configuration for the Mongo template: ? mongoTemplate.upsert(query, update, User. class ); https://docs.google.com/​document/d/1XltsJam-0q6TmiMc8iK192UxS5rw04kTjO22ycN4vvc/edit. 0. There are several convenient methods onMongoTemplatefor saving and inserting yourobjects. To have more fine grained control over the conversion processyou can register Spring converters with theMappingMongoConverter, for exampleConverter<Person, DBObject>andConverter<DBObject, Person>. Note.

To return the document with the modifications made on the update, use the new option. The findAndModify() method is a shell helper around the findAndModify This lets you update documents that do not meet the validation requirements. is specified for the collection or for the operations, MongoDB uses the simple  The save operation has save-or-update semantics: if an id is present, it performs an update, if not – it does an insert. Let's look at the first semantic – the insert; here's the initial state of the database: { } When we now save a new user: User user = new User(); user.setName("Albert"); mongoTemplate.save(user, "user");

The examples on this page use the inventory collection. To create and/or populate the inventory collection, run the following:. The design goal was to make it as easy as possible to transition between the use of the base MongoDB driver and MongoOperations. A major difference between the two APIs is that MongoOperations can be passed domain objects instead of Document.

Comments
  • @starkk92 plz note that Update.fromDBObject will replace all fields in dbDoc. If u just want to create Update with non-null fields, u have to code it yourself.
  • OK for the answer, but this also sets null objects. If you don't want null objects to be updated, you have to include an ObjectMapper with the option to ignore inlcudes. This is @gogstad comment on Vivek Sethi's answer. Thanks by the way.
  • why does this fail to work for BulkOperations any idea here is a snippet of my code pastebin.com/t0mZDZd8 java.lang.IllegalArgumentException: Invalid BSON field name code
  • @madcolonel10 did you find any solution to this? I have the same problem.
  • @chris115379 check if this helps pastebin.com/LxEPym3S
  • You need to make sure the ObjectMapper doesn't serialize nulls: String jsonStr = objectMapper.copy().setSerializationInclusion(JsonInclude.Include.NON_NULL).writeValueAsString(object);
  • caveat: If you are using a @Version - tagged field in your entity, this approach will interfere with spring's version incrementation, producing an exception "Invalid BSON field name $inc". In this case, one must iterate over the dbDoc and use update.set like in @PaniniGelatos answer.
  • Code only answers are really discouraged. To help future readers, please explain what you are doing too!