MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Pobieranie określonego klucza MongoDB z DuplicateKeyException, który został faktycznie zduplikowany (Java/Spring)

Niezupełnie, ponieważ Mongo Java Driver już ujawnia ostatni błąd jako skonstruowany ciąg znaków:

writeResult.getLastError().get("err") zwraca coś takiego jak:

insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.person.$username dup key: { : "joe" }

Odnosi się to również do powłoki i każdego sterownika, jak sobie wyobrażam.

Myślę, że rozsądnym rozwiązaniem jest przeanalizowanie takiego zduplikowanego wyjątku klucza przy użyciu niestandardowego wyjątku:

public class DetailedDuplicateKeyException extends DuplicateKeyException {
    public DetailedDuplicateKeyException(String msg) {
        // Instead of just calling super parse the message here.
        super(msg);
    }
}

... niestandardowy tłumacz wyjątków:

public class DetailedDuplicateKeyExceptionTransaltor extends MongoExceptionTranslator {

    @Override
    public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
        if (ex instanceof MongoException.DuplicateKey) {
            return new DetailedDuplicateKeyException(ex.getMessage());
        }
        return super.translateExceptionIfPossible(ex);
    }
}

... i poprawnie ustawić konfigurację Spring:

@Bean
public MongoFactoryBean mongo() {
    MongoFactoryBean mongo = new MongoFactoryBean();
    mongo.setExceptionTranslator(new DetailedDuplicateKeyExceptionTransaltor());
    mongo.setHost("localhost");
    return mongo;
}

EDYTUJ

Po sprawdzeniu MongoTemplate kod (1.4.1.RELEASE), wydaje się, że wewnętrznie SimpleMongoDbFactory służy do pobierania domyślnego MongoExceptionTranslator , więc ten utworzony za pomocą MongoFactoryBean jest zacieniony. Przeoczyłem tę część.

Rozwiązaniem jest zastąpienie SimpleMongoDbFactory (zapomnij o MongoFactoryBean , jest to bezużyteczne w tym kontekście):

public class MySimpleMongoDbFactory extends SimpleMongoDbFactory {

    PersistenceExceptionTranslator translator = new       
            DetailedDuplicateKeyExceptionTransaltor();

    public MySimpleMongoDbFactory(Mongo mongo, String databaseName) {
        super(mongo, databaseName);
    }

    @Override
    public PersistenceExceptionTranslator getExceptionTranslator() {
        return translator;
    }
}

Teraz możesz skonstruować szablon za pomocą niestandardowego MongoDbFactory :

template = new MongoTemplate (new MySimpleMongoDbFactory(new MongoClient(), "test"));

Próbowałem, a ten działa dla mnie.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Referencje a osadzania w MongoDB

  2. Jak mogę połączyć wiele kolekcji w jedną kolekcję za pomocą $lookup mongodb lub nodejs mongodb?

  3. 3 sposoby na ukrycie indeksu w planie zapytań w MongoDB

  4. 5 sposobów na uzyskanie godziny z daty w MongoDB

  5. Jak zaktualizować pole _id w dokumencie mongodb?