vert.x - MongoClient::save(...) 如何更改文档参数的 _id 字段
问题描述
我有一个User
嵌入 aJsonObject
来表示用户字段的类。这个类看起来像这样:
class User {
private JsonObject data;
public User(...) {
data = new JsonObject();
data.put("...", ...).put(..., ...);
}
public String getID() { return data.getString("_id"); }
// more getters, setters
// DB access methods
public static userSave(MongoClient mc, User user){
// some house keeping
mc.save("users", user.jsonObject(), ar -> {
if(ar.succeeded()) { ... } else { ... }
});
}
}
我刚刚花了半天多的时间试图弄清楚为什么调用user.getID()
有时会产生以下错误:ClassCastException: class io.vertx.core.json.JsonObject cannot be cast to class java.lang.CharSequence
. 我缩小到方法,userSave()
更具体地说,MongoClient::save()
它实际上会产生副作用,将data._id
"_id" : "5ceb8ebb9790855fad9be2fc"
变成类似的东西
"_id" : {
"$oid" : "5ceb8ebb9790855fad9be2fc"
}
vertx 文档证实了这一点,该文档指出“此操作可能会更改文档参数的 _id 字段”。这实际上也适用于其他写入方法,如插入。
我提出了两个解决方案,并且很少有关于在save()
保持该_id
领域最新的同时正确执行的问题。
S1实现此目的的一种方法是保存 Json 对象的副本而不是对象本身,换句话说:mc.save("users", user.jsonObject().copy(), ar -> {...});
. 从长远来看,这可能会很昂贵。
S2另一种方法是“记住” _id
,然后将其重新插入到data
该部分中的对象中if(ar.succeeded()) {data.put("_id", oidValue); ...}
。但是由于我们是异步的,我不认为save()
和之间的间隔data.put(...)
是原子的?
Q1:解决方案S1假设 ID 不变,即字符串5ceb8ebb9790855fad9be2fc
不变。我们对此有保修吗?
Q2:正确实施的saveUser()
正确方法是什么?
编辑:用于创建的配置 JSON 对象用户MongoClient
如下(以防出现问题):
"main_pool" : {
"pool_name" : "mongodb",
"host" : "localhost",
"port" : 27017,
"db_name" : "appdb",
"username" : "xxxxxxxxx",
"password" : "xxxxxxxxx",
"authSource" : "admin",
"maxPoolSize" : 5,
"minPoolSize" : 1,
"useObjectId" : true,
"connectTimeoutMS" : 5000,
"socketTimeoutMS" : 5000,
"serverSelectionTimeoutMS" : 5000
}
解决方案
推荐阅读
- c# - Jwt Bearer 和依赖注入
- matlab - 扩展卡尔曼滤波器预测更新时间
- python - 从文本中的缩写中查找首字母缩写词
- c# - 在 UI 元素设置期间忽略属性设置调用
- json - 将 json 列表发布到烧瓶路由时出现 TypeError
- mysql - 我正在尝试在触发器上使用算术,但我的触发器不起作用
- c# - Swashbuckle 多态性需要鉴别器作为更新时的第一个属性
- java - 我正在开发一个 spring mvc 项目,我想从两个下拉框和一个文本框提交值
- android - 有什么地方可以上传两个要翻译的字符串 xml 文件吗?
- javascript - 检查样本库/文档 Vue JS 中是否出现相同的值