Pas vraiment, car le pilote Java Mongo expose déjà la dernière erreur sous forme de chaîne construite :
writeResult.getLastError().get("err")
renvoie quelque chose comme :
insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.person.$username dup key: { : "joe" }
C'est également vrai pour le shell et chaque pilote, j'imagine.
Une solution raisonnable, je pense, consiste à analyser cette exception de clé en double à l'aide d'une exception personnalisée :
public class DetailedDuplicateKeyException extends DuplicateKeyException {
public DetailedDuplicateKeyException(String msg) {
// Instead of just calling super parse the message here.
super(msg);
}
}
... un traducteur d'exception personnalisé :
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);
}
}
... et définir correctement la configuration de Spring :
@Bean
public MongoFactoryBean mongo() {
MongoFactoryBean mongo = new MongoFactoryBean();
mongo.setExceptionTranslator(new DetailedDuplicateKeyExceptionTransaltor());
mongo.setHost("localhost");
return mongo;
}
MODIFIER
Après avoir inspecté MongoTemplate
code (1.4.1.RELEASE), il semble qu'en interne un SimpleMongoDbFactory
est utilisé pour récupérer un MongoExceptionTranslator
par défaut , donc celui créé avec MongoFactoryBean
est ombragé. Avait manqué cette partie.
La solution consiste à remplacer SimpleMongoDbFactory
(oubliez MongoFactoryBean
, ça ne sert à rien dans ce contexte):
public class MySimpleMongoDbFactory extends SimpleMongoDbFactory {
PersistenceExceptionTranslator translator = new
DetailedDuplicateKeyExceptionTransaltor();
public MySimpleMongoDbFactory(Mongo mongo, String databaseName) {
super(mongo, databaseName);
}
@Override
public PersistenceExceptionTranslator getExceptionTranslator() {
return translator;
}
}
Vous pouvez maintenant créer un modèle à l'aide de la MongoDbFactory
personnalisée :
template = new MongoTemplate
(new MySimpleMongoDbFactory(new MongoClient(), "test"));
J'avais essayé, et celui-ci fonctionne pour moi.