Spring Data和Mongo Java驱动程序的错误处理

问题描述 投票:0回答:1

我在与MongoDB交互时难以理解如何正确接收和处理数据库约束错误。

我正在使用:

  • MongoDB Java驱动程序-2.11
  • spring-data-mongodb-1.2.1.RELEASE
  • spring-framework-core-3.1.0.RELEASE

我正在使用mongoTemplate.insert,并为其指定一个代表足球队的“ persistentTeam”对象。我习惯于根据一些业务规则生成文档的_id字段。生成此_id的算法可能会与现有对象匹配,在这种情况下,我想进行一些错误处理。

使用默认配置,如果我插入具有重复ID的对象,则不会从数据库返回任何错误。这与mongo文档相矛盾,该文档说默认的mongo驱动程序配置为“ ACKNOWLEDGED”,在这种情况下应该引发异常:http://docs.mongodb.org/manual/release-notes/drivers-write-concern/我查看了2.11 mongo驱动程序代码,可以肯定的是,在Mongo.java中,默认写关注点为WriteConcern。正常(相当于UNACKNOWLEDGED)。好吧,我会解决的。

编辑:关于代码/文档差异的一些附加说明:Mongo Java驱动程序2.10.0引入了MongoClient.java,它取代了Mongo.java。但是,spring-framework-core 3.1.0.RELEASE没有与此新类集成。这就是为什么我没有获得期望的默认值的原因。

我更新了我的mongo工厂:

<bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
    <property name="host" value="${db.url}" />
    <property name="writeConcern" value="ACKNOWLEDGED" />
</bean>

现在,当我尝试使用重复的主键插入对象时,出现以下错误:

{"com.mongodb.MongoException$DuplicateKey: {
\"serverUsed\" : \"localhost/127.0.0.1:27017\" ,
\"err\" : \"E11000 duplicate key error index: Sports.persistentTeam.$_id_  dup key: { : 5019964551640473690 }\" ,
\"code\" : 11000 ,
\"n\" : 0 ,
\"connectionId\" : 21 , \"ok\" : 1.0}\n
\tat com.mongodb.CommandResult.getException(CommandResult.java:74)\n
\tat com.mongodb.CommandResult.throwOnError(CommandResult.java:110)\n
\tat com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:102)\n
\tat com.mongodb.DBTCPConnector.say(DBTCPConnector.java:142)\n
\tat com.mongodb.DBTCPConnector.say(DBTCPConnector.java:115)\n
\tat com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:248)\n
\tat com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:204)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:76)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:60)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:105)\n
\tat org.springframework.data.mongodb.core.MongoTemplate$8.doInCollection(MongoTemplate.java:835)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:388)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insertDBObject(MongoTemplate.java:830)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:659)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:613)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:604)\n
\tat com.example.persistence.dao.MongoDataServiceDao.create(MongoDataServiceDao.java:96)\n
\tat com.example.persistence.PersistenceImpl.createObject(PersistenceImpl.java:944)\n
}

好,太好了!一切正常。好吧,不是。当我尝试插入应该成功的内容时,出现此错误:

{
com.mongodb.WriteConcernException: 
{ \"serverUsed\" : \"localhost/127.0.0.1:27017\" ,
\"n\" : 0 ,
\"connectionId\" : 20 ,
\"wnote\" : \"no replication has been enabled, so w=\\\"ACKNOWLEDGED\\\" won't work\" ,
\"err\" : \"norepl\" ,
\"ok\" : 1.0}
\n\tat com.mongodb.CommandResult.getException(CommandResult.java:77)\n
\tat com.mongodb.CommandResult.throwOnError(CommandResult.java:110)\n
\tat com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:102)\n
\tat com.mongodb.DBTCPConnector.say(DBTCPConnector.java:142)\n
\tat com.mongodb.DBTCPConnector.say(DBTCPConnector.java:115)\n
\tat com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:248)\n
\tat com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:204)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:76)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:60)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:105)\n
\tat org.springframework.data.mongodb.core.MongoTemplate$8.doInCollection(MongoTemplate.java:835)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:388)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insertDBObject(MongoTemplate.java:830)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:659)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:613)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:604)\n
\tat com.example.mongo.persistence.dao.MongoDataServiceDao.create(MongoDataServiceDao.java:96)\n
\tat com.example.persistence.PersistenceImpl.createObject(PersistenceImpl.java:944)\n
}

所以这有点令人困惑。该错误告诉我,如果没有复制,我将无法使用ACKNOWLEDGED。但是documentaton并没有这样说。还有其他WriteConcern模式可以明确声明它们检查是否已复制副本... ACKNOWLEDGED仅应验证对主数据库的写入。毕竟,写入实际上成功了。我在这里做什么?只需掩埋第二个例外,然后忘记它?

java mongodb spring-data-mongodb
1个回答
1
投票

这是因为您使用的是WriteConcern的String变体。

这样,您的驱动程序会将其视为设置为Write Concern的副本标签。因此,例外。

将int变体用于WriteConcern构造函数,并为其赋予1的值(与{w=1}相同),这是确认的值。

© www.soinside.com 2019 - 2024. All rights reserved.