Non proprio, poiché il driver Mongo Java espone già l'ultimo errore come una stringa costruita:
writeResult.getLastError().get("err")
restituisce qualcosa come:
insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.person.$username dup key: { : "joe" }
Questo vale anche per la shell e tutti i driver, immagino.
Una soluzione ragionevole, penso, è analizzare tale eccezione di chiave duplicata utilizzando un'eccezione personalizzata:
public class DetailedDuplicateKeyException extends DuplicateKeyException {
public DetailedDuplicateKeyException(String msg) {
// Instead of just calling super parse the message here.
super(msg);
}
}
... un traduttore di eccezioni personalizzato:
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);
}
}
... e impostando correttamente la configurazione Spring:
@Bean
public MongoFactoryBean mongo() {
MongoFactoryBean mongo = new MongoFactoryBean();
mongo.setExceptionTranslator(new DetailedDuplicateKeyExceptionTransaltor());
mongo.setHost("localhost");
return mongo;
}
MODIFICA
Dopo aver controllato MongoTemplate
codice (1.4.1.RELEASE), sembra che internamente una SimpleMongoDbFactory
viene utilizzato per recuperare un MongoExceptionTranslator
predefinito , quindi quello creato con MongoFactoryBean
è in ombra. Avevo perso quella parte.
La soluzione è sovrascrivere SimpleMongoDbFactory
(dimentica MongoFactoryBean
, è inutile in questo contesto):
public class MySimpleMongoDbFactory extends SimpleMongoDbFactory {
PersistenceExceptionTranslator translator = new
DetailedDuplicateKeyExceptionTransaltor();
public MySimpleMongoDbFactory(Mongo mongo, String databaseName) {
super(mongo, databaseName);
}
@Override
public PersistenceExceptionTranslator getExceptionTranslator() {
return translator;
}
}
Ora puoi costruire un modello usando il MongoDbFactory
personalizzato :
template = new MongoTemplate
(new MySimpleMongoDbFactory(new MongoClient(), "test"));
Ci avevo provato e questo funziona per me.