使用实体属性生成morphia更新文档而不是替换它(保留不映射的属性)

时间:2015-04-09 20:55:52

标签: java mongodb replace morphia

给出mongodb集合中的示例文档:

{"_id": 100, "name": "User Name", "sideField": "some value"}

和morphia的实体:

@Entity()
public class User {
  @Id public long id;
  public String name;
}

是否可以使用以下示例用户对象

更新mongodb文档
User user = new User();
user.id = 100;
user.name = "New Name";

这样Morphia就不会删除" sideField"属性?

默认情况下,当我使用Morphia的Datastore.save(...)方法时,Morphia将给定_id下的整个文档替换为从实体构建的新文档,删除所有未映射到实体的属性。我知道我可以制作"手册"所选字段的更新,但这不是我将Object Mapper添加到项目依赖项的原因。

2 个答案:

答案 0 :(得分:1)

最后,我放弃了Morphia并使用MongoDB Java驱动程序API 3.0.0和Jackson解决了这个问题:

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

当然这只适用于简单的更新,但对我的情况来说已经足够了。

答案 1 :(得分:0)

您可以执行更新而不是保存。但是,对于此更新,您将需要一个标识对象的查询:

update(Query<T> q, UpdateOperations<T> updateOptions);

然后,在您从REST API获取的对象上,您需要遍历所有模型属性(在您的案例名称,id,sideField中),并将updateOperations添加到非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);

上面的代码会在您的数据库中更新_id == user.id字段名称和sideField(如果它们不为空)。

当然,您可以将此代码添加为模型中的方法,并使用反射从模型中获取所有属性,然后检查它们是否不是,如果不是,请将它们添加到UpdateOperations。

相关问题