2013-05-09 7 views
9

Я получаю эту ошибку [2] время от времени при попытке повысить (увеличить или вставить) документ с помощью метода [1].Mongodb upsert throwing DuplicateKeyException

[1]

public NGram save(final NGram ngram) { 
    Criteria cr = where("_id").is(ngram.getNgram()) 
      .and("f3c").is(ngram.getF3c()) 
      .and("tokCount").is(ngram.getTokCount()) 
      .and("first").is(ngram.getFirst()) 
      ; 
    if(ngram.getTokCount() > 1) { 
     cr.and("second").is(ngram.getSecond()); 
    } 
    if(ngram.getTokCount() > 2) { 
     cr.and("third").is(ngram.getThird()); 
    } 
    final Query qry = new Query(cr); 
    final Update updt = new Update().inc("count", ngram.getCount()); 
    template.upsert(qry, updt, NGram.class); 
    return ngram; 
} 

[2]

Caused by: org.springframework.dao.DuplicateKeyException: E11000 duplicate key error index: sytrue.ngram.$_id_ dup key: { : "page two" }; nested exception is com.mongodb.MongoException$DuplicateKey: E11000 duplicate key error index: sytrue.ngram.$_id_ dup key: { : "page two" } 
at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:52) 
at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:1665) 
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:390) 
at org.springframework.data.mongodb.core.MongoTemplate.doUpdate(MongoTemplate.java:920) 
at org.springframework.data.mongodb.core.MongoTemplate.upsert(MongoTemplate.java:894) 
at com.sytrue.ngram.repo.impl.NGramRepositoryImpl.save(NGramRepositoryImpl.java:43) 
at sun.reflect.GeneratedMethodAccessor41.invoke(Unknown Source) 

Upsert никогда не должен возвращать мне это исключение. Я прав?

+0

случайно, одновременно возникают два восходящего потока? –

+0

нет, я сериализую эти upserts через очередь. – biliboc

ответ

16

Вопрос, который я только предполагаю, может быть следующим:

Вы делаете операции поиска на основе многих критериев. Это означает, что если это не удается из-за какого-либо несоответствия параметра (в критериях), он попытается вставить документ.

Итак, есть вероятность, что вы пытаетесь обновить один и тот же документ одним и тем же _id, но некоторые другие критерии не совпадают, в результате чего он снова вставлен, что вызовет дублирующее ключевое исключение. Рассмотрим приведенный ниже пример

test:Mongo > db.example.update({ _id : 1, a : 1, b : 1},{ $set : {d : 1}}, true, false) 
test:Mongo > db.example.find() 
{ "_id" : 1, "a" : 1, "b" : 1, "d" : 1 } 
test:Mongo > db.example.update({ _id : 1, a : 1, b : 2},{ $set : {d : 1}}, true, false) 
E11000 duplicate key error index: test.example.$_id_ dup key: { : 1.0 } 
Смежные вопросы