簡體   English   中英

使用 Spring Data 和 Mongo Java Driver 進行錯誤處理

[英]Error Handling with Spring Data and Mongo Java Driver

在與 MongoDB 交互時,我在理解如何正確接收和處理數據庫約束錯誤時遇到了一些麻煩。

我在用着:

  • MongoDB Java 驅動程序 - 2.11
  • spring-data-mongodb - 1.2.1.RELEASE
  • 彈簧框架核心 - 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.NORMAL(相當於UNACKNOWLEDGED)。 好的,我會解決的。

編輯:關於代碼/文檔差異的一些附加說明:Mongo Java Driver 2.10.0 引入了替換 Mongo.java 的 MongoClient.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 應該只驗證對主要的寫入。 畢竟,寫入實際上成功了。 我在這里做什么? 只是埋葬第二個例外並忘記它?

這是因為您使用的是WriteConcern的 String 變體。

這樣,您的驅動程序會將其視為副本標記集 Write Concern。 因此例外。

WriteConcern構造函數使用 int 變體,並為其賦予值1 (如在{w=1} ),這是確認的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM