【问题标题】:Spring Data MongoRepository save() method cause E11000 Duplicate Key errorSpring Data MongoRepository save() 方法导致 E11000 Duplicate Key 错误
【发布时间】:2022-11-02 17:33:52
【问题描述】:

我使用 MongoRepository 的 save() 方法上插一些实体。 但是,有时我会遇到这样的重复错误。

org.springframework.dao.DuplicateKeyException: E11000 duplicate key error collection: test.collection index: _id_ dup key: { : "N__3EmZi__C__101503567" }; nested exception is com.mongodb.MongoWriteException: E11000 duplicate key error collection: test.collection index: _id_ dup key: { : "N__3EmZi__C__101503567" }
    at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:106) ~[spring-data-mongodb-3.2.11.jar!/:3.2.11]
    at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2899) ~[spring-data-mongodb-3.2.11.jar!/:3.2.11]
    at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:555) ~[spring-data-mongodb-3.2.11.jar!/:3.2.11]
    at org.springframework.data.mongodb.core.MongoTemplate.saveDocument(MongoTemplate.java:1507) ~[spring-data-mongodb-3.2.11.jar!/:3.2.11]
    at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:1443) ~[spring-data-mongodb-3.2.11.jar!/:3.2.11]
    at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:1385) ~[spring-data-mongodb-3.2.11.jar!/:3.2.11]
    at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:94) ~[spring-data-mongodb-3.2.11.jar!/:3.2.11]

在我看来,'save()' 方法是 upsert,所以我认为不能出于任何原因发生重复错误,但我不确定原因是什么。

这是我的实体:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "collection")
@Sharded(shardKey = {"cust_doc_id", "sto_doc_id"}, shardingStrategy = ShardingStrategy.RANGE)
public class Entity {

    @Id
    private String id;

    @Field("cust_doc_id")
    private String customerDocId;

    @Field("sto_doc_id")
    private String storeDocId;

}

有没有办法解决这个重复的错误?

【问题讨论】:

  • 您使用的是什么版本的驱动程序和数据库?当您.save() 时,该文档是什么样的?

标签: java spring mongodb spring-data-mongodb


【解决方案1】:

我面临着类似的情况。当使用 mongoTemplate save 方法保存记录时,偶尔会抛出 DuplicateKeyException。 save 方法应该在内部使用 upsert,这在正常情况下不应该发生。到目前为止,我无法在测试环境中重现这一点,而只能偶尔在生产环境中重现。当前使用的版本:

  • MongoDB:3.4.12

  • mongodb-驱动程序同步:4.6.0

  • spring-boot-starter-data-mongodb:2.7.0

  • 弹簧启动:2.7.0

    org.springframework.dao.DuplicateKeyException: 服务器 mongodb1:27017 上的写入操作错误。写入错误:WriteError{code=11000, message='E11000 重复键错误集合:push-db.devices 索引:IDdup key: { : { platformId: 15, uuid: "eW9Zale3ST2EPPtFLQf3R5:APA91bGcXIc4ZIQZ3qVNTp1nDo981oPmj4CR5EXJspU-Ge_oQq1b12v0HLP7E-CPjF5qrK44K7Zr5Fszl0c6tGEmboKg2QrZoQpwFTAb6a_pICvX8V8ZJwbVIW1aMrC..." } }', details={}}.; 嵌套异常是 com.mongodb.MongoWriteException: 服务器 mongodb1:27017 上的写入操作错误。写入错误:WriteError{code=11000, message='E11000 重复键错误集合:push-db.devices 索引:IDdup key: { : { platformId: 15, uuid: "eW9Zale3ST2EPPtFLQf3R5:APA91bGcXIc4ZIQZ3qVNTp1nDo981oPmj4CR5EXJspU-Ge_oQq1b12v0HLP7E-CPjF5qrK44K7Zr5Fszl0c6tGEmboKg2QrZoQpwFTAb6a_pICvX8V8ZJwbVIW1aMrC..." } }', details={}}.在 org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:106) 在 org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:3044) 在 org.springframework.data.mongodb .core.MongoTemplate.execute(MongoTemplate.java:600) at org.springframework.data.mongodb.core.MongoTemplate.saveDocument(MongoTemplate.java:1595) at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate .java:1530) 在 org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:1473) 在 org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:1458)

我可以看到索引 _id 存在。

   {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "push-db.devices"
    }

在 mongodb 集合中,数据看起来像这样。 id 由 platformId 和 uuid 组成:

  {
    "_id" : {
        "platformId" : 15,
        "uuid" : "eW9Zale3ST2EPPtFLQf3R5:APA91bGcXIc4ZIQZ3qVNTp1nDo981oPmj4CR5EXJspU-Ge_oQq1b12v0HLP7E-CPjF5qrK44K7Zr5Fszl0c6tGEmboKg2QrZoQpwFTAb6a_pICvX8V8ZJwbVIW1aMrCasq2323232"
    },
    "appId" : 32342,
    "appVersion" : "33.556.66",
    "tags" : [ 
        {
            "_id" : 39391,
            "lastLogin" : NumberLong(1666903871334),
            "loginCount" : 1
        }, 
        {
            "_id" : 34269,
            "lastLogin" : NumberLong(1666903871526),
            "loginCount" : 1
        }
    ],
    "_class" : "com.myCompany.device.PushDevice"
}

保存数据的Java sn-p:

private final MongoTemplate mongoTemplate;

  @Override
  public void storeDevice(PushDevice device) {
      mongoTemplate.save(device);
  }

Mongodb 作为 3 个服务器的复制集运行。我尝试将驱动程序更新到最新版本,但没有帮助。对解决方案的任何提示将不胜感激。

【讨论】:

    猜你喜欢
    • 2018-10-02
    • 1970-01-01
    • 2016-04-10
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 2012-06-07
    • 2022-01-05
    相关资源
    最近更新 更多