Java 使morphia更新文档具有实体属性,而不是替换它(保留未映射的属性)

Java 使morphia更新文档具有实体属性,而不是替换它(保留未映射的属性),java,mongodb,replace,morphia,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 = "Ne

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下的整个文档替换为从实体构建的新文档,以这种方式删除所有未映射到实体的属性。我知道我可以对所选字段进行“手动”更新,但这不是我将对象映射器添加到项目依赖项的原因

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

update(Query<T> q, UpdateOperations<T> updateOptions);
update(查询q、更新操作更新操作);
然后,在从REST API获得的对象上,需要遍历所有模型属性(在您的案例中为name、id、sideField),并将不为null的属性添加到updateOperations中:

//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);
//从REST API获取的用户。
User=fetchUserFromAPI(…);
UpdateOperations updateOptions=ds.createUpdateOperations(User.class);
如果(user.name!=null){updateOptions.set(“name”,user.name);}
如果(user.name!=null){updateOptions.set(“sideField”,user.sideField);}
update(ds.createQuery(User.class).field(“_id”).equal(User.id),updateOptions);
如果字段name和sideField不为空,则上面的代码将在数据库中用
\u id==user.id
更新


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

最后,我放弃了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);

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

很遗憾,这是不可能的。谢谢你@MarkusWMahlberg,这正是我害怕的。我可能会回到Morphia.toDBObject(…),然后从数据库中与DBObject进行一些神奇的合并,最后使用标准mongodb api替换文档。如果您想更改某个内容,为什么不直接加载原始实体呢?实际上,我想从JSON文档创建Java bean的唯一原因是验证它。不是整个文件,只是其中的一小部分。也许我应该试试——json模式规范的唯一java实现。也许你应该详细描述你的用例。我确信我们可以找到一个解决方案。Thx,但是在这个方法中没有对象映射,我不需要Morphia。我可以直接在MongoDB驱动程序的API中完成。