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

vikingsteve picture vikingsteve · Nov 15, 2013 · Viewed 47.2k times · Source

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.

Answer

PaniniGelato picture PaniniGelato · Jan 22, 2016

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);