我们使用的是MongoDB 2.6.12,最近将Camel升级到2.18.1,将“mongo-java-driver”升级到3.4.1。
我们正在使用Camel组件“camel-mongodb”并有一条路线:
set -o errexit
“MyProcessor”基本上如下所示:
<camel:route id="save">
<from uri="direct:save"/>
<camel:process ref="myProcessor"/>
<camel:to uri="mongodb:mongoDBConnectionBean?database=abc&collection=xyz&operation=save"/>
</camel:route>
结果是对象存储在MongoDB中,但由于某种原因,“_ id”字段设置为“null”。这种情况以前没有发生过。
我仔细研究了org.apache.camel.component.mongodb.MongoDbProducer.createDoSave这段代码执行“upsert”的地方:
public void process(Exchange exchange) {
Object body = exchange.getIn().getBody();
if (body instanceof DBObject) {
DBObject newObject = (DBObject) body;
//some more logic here manipulating "newObject"
//but "newObject" does not have a field "_id"
exchange.getIn().setBody(newObject);
} else {
exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
}
}
现在我认为问题是“replaceOne”上的MongoDB采用“queryObject”的“_id”(在我的情况下为null),并使用“_id”插入“saveObj”。(参见: MongoDB Java Client stores "_id" as null on "replaceOne")
这种行为也可以在mongo shell中看到:
MongoCollection e = this.calculateCollection(exchange1);
BasicDBObject saveObj = (BasicDBObject)exchange1.getIn().getMandatoryBody(BasicDBObject.class);
UpdateOptions options = (new UpdateOptions()).upsert(true);
BasicDBObject queryObject = new BasicDBObject("_id", saveObj.get("_id"));
UpdateResult result = e.replaceOne(queryObject, saveObj, options);
因此,一方面我认为这是mongo-camel组件代码中的一个问题,另一方面我认为我必须遗漏一些东西,因为很多人会遇到这个问题。