MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Извличане на конкретния MongoDB ключ от DuplicateKeyException, който всъщност е дублиран (Java/Spring)

Всъщност не, тъй като драйверът на Mongo Java вече излага последната грешка като конструиран низ:

writeResult.getLastError().get("err") връща нещо като:

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

Това важи и за обвивката и всеки драйвер, предполагам.

Мисля, че разумно решение е да се анализира такова дублирано ключово изключение с помощта на персонализирано изключение:

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

... персонализиран преводач на изключения:

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

... и правилна настройка на Spring конфигурацията:

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

РЕДАКТИРАНЕ

След проверка на MongoTemplate код (1.4.1.RELEASE), изглежда, че вътрешно SimpleMongoDbFactory се използва за извличане на стандартен MongoExceptionTranslator , така че този, създаден с MongoFactoryBean е засенчен. Бях пропуснал тази част.

Решението е да замените SimpleMongoDbFactory (забравете за MongoFactoryBean , безполезно е в този контекст):

public class MySimpleMongoDbFactory extends SimpleMongoDbFactory {

    PersistenceExceptionTranslator translator = new       
            DetailedDuplicateKeyExceptionTransaltor();

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

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

Сега можете да създадете шаблон, като използвате персонализирания MongoDbFactory :

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

Опитах и ​​това работи за мен.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Предупреждение за оттегляне на MongoDB mongoose

  2. MongoDB няма да се свърже с MongoHQ с помощта на Mongoid

  3. Как да сортирам масив в запис на колекция в MongoDB?

  4. Как да актуализирате поле, като използвате предишната му стойност в MongoDB/Mongoose

  5. Актуализацията на Mongodb с upsert е неуспешна