MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Abrufen des spezifischen MongoDB-Schlüssels von DuplicateKeyException, der tatsächlich dupliziert wurde (Java/Spring)

Nicht wirklich, da der Mongo Java Driver bereits den letzten Fehler als konstruierten String ausgibt:

writeResult.getLastError().get("err") gibt etwas zurück wie:

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

Das gilt auch für die Shell und jeden Treiber, nehme ich an.

Eine vernünftige Lösung ist meines Erachtens, eine solche doppelte Schlüsselausnahme mit einer benutzerdefinierten Ausnahme zu analysieren:

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

... ein benutzerdefinierter Ausnahmeübersetzer:

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);
    }
}

... und die Spring-Konfiguration richtig einstellen:

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

BEARBEITEN

Nach der Überprüfung von MongoTemplate code (1.4.1.RELEASE), scheint intern eine SimpleMongoDbFactory wird verwendet, um einen standardmäßigen MongoExceptionTranslator abzurufen , also die mit MongoFactoryBean erstellte ist beschattet. Hatte diesen Teil verpasst.

Die Lösung besteht darin, SimpleMongoDbFactory zu überschreiben (Vergessen Sie MongoFactoryBean , ist in diesem Zusammenhang nutzlos):

public class MySimpleMongoDbFactory extends SimpleMongoDbFactory {

    PersistenceExceptionTranslator translator = new       
            DetailedDuplicateKeyExceptionTransaltor();

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

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

Jetzt können Sie mithilfe der benutzerdefinierten MongoDbFactory eine Vorlage erstellen :

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

Hatte es versucht, und dieses funktioniert bei mir.