Reputation: 1315
Given example document in mongodb collection:
{"_id": 100, "name": "User Name", "sideField": "some value"}
and Entity for morphia:
@Entity()
public class User {
@Id public long id;
public String name;
}
is it possible to update mongodb document with following example User object
User user = new User();
user.id = 100;
user.name = "New Name";
so that Morphia would not delete "sideField" attribute?
By default when I use Morphia's Datastore.save(...) method, Morphia replaces whole document under given _id with new one, built from entity, deleting this way all attributes not mapped to entity. I know I can make "manual" updates of selected fields, but that's not why I added Object Mapper to project's dependencies.
Upvotes: 1
Views: 2851
Reputation: 1315
Finally, I have dropped Morphia and solved problem using MongoDB Java driver API 3.0.0 and Jackson like this:
String updateJson = .... //I get JSON String via REST API
// here, if I want to validate update I use JSON Schema
// or Jackson (to map updateJson to object and validate it with javax.validation)
Document updateDoc = Document.parse(updateJson);
Document setUpdate = new Document("$set", updateDoc);
mongoDb.getCollection("COLL").updateOne(Filters.eq("_id", someID), setUpdate);
Of course this works only for simple updates but is enough for my case.
Upvotes: 1
Reputation: 2086
You can perform an update instead of a save. For this update, however, you will need a query which identifies your object:
update(Query<T> q, UpdateOperations<T> updateOptions);
Then on the object you get from the REST API you need to go through all the model attributes (in your case name, id, sideField) and add to the updateOperations the ones which are not null:
//User fetched from the REST API.
User user = fetchUserFromAPI(...);
UpdateOperations<T> updateOptions = ds.createUpdateOperations(User.class);
if(user.name != null){updateOptions.set("name", user.name);}
if(user.name != null){updateOptions.set("sideField", user.sideField);}
ds.update(ds.createQuery(User.class).field("_id").equal(user.id), updateOptions);
That code above will update in your DB with _id == user.id
the fields name and sideField if they are not empty.
Of course you could add this code as a method on your model and use reflection to get all the attributes from the model and then check if they are not and in case they are not, add them to the UpdateOperations.
Upvotes: 0