2013-05-09 22 views
9

Ricevo questo errore [2] di volta in volta quando si tenta di aumentare (incrementare o inserire) un documento utilizzando il metodo [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 dovrebbe mai mi tornare questa eccezione. Ho ragione?

+0

per caso, due upster che si verificano nello stesso momento? –

+0

no, sto serializzando questi ups su una coda. – biliboc

risposta

16

Il problema che sto solo indovinando potrebbe essere seguente:

si sta facendo operazioni di ricerca in base a diversi criteri. Ciò significa che se fallisce a causa di una mancata corrispondenza di un parametro (nei criteri), tenterà di inserire il documento.

Quindi, è probabile che si stia tentando di aggiornare lo stesso documento con lo stesso _id ma alcuni degli altri criteri non corrispondono, causando l'inserimento di nuovo che causerà un'eccezione chiave duplicata. Considera l'esempio di seguito

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 }