Spring Data MongoDB: преобразование BigInteger в ObjectId

У меня проблема с запросом на обновление с использованием Spring Data MongoDB. Я получаю _id некоторого объекта как значение BigInteger. Затем я хочу сделать следующий запрос:

Query query = new Query(Criteria.where("_id").is(id));
Update update = new Update();
update.set("version",version);
mongoOperations.updateFirst(query, update, Audit.class);

Часть запроса не соответствует ни одному документу, поскольку значение идентификатора, переданное в is(), каким-то образом должно быть преобразовано в ObjectId. Я не могу найти никакой документации по такому преобразованию. Будем признательны за любую помощь.

p.s.: SpringData Mongodb версии 1.2


person Aleksandr Kravets    schedule 08.07.2013    source источник
comment
Я также вижу, что вы пытаетесь выполнить какое-то управление версиями. Я хотел бы отослать вас к этому вопрос, который я задал для аудита с помощью Spring Mongo, так как он также позволяет настроить автоматическое управление версиями с использованием аннотаций.   -  person Trevor Gowing    schedule 09.07.2013
comment
Спасибо, но я достаточно доволен своей версией :-)   -  person Aleksandr Kravets    schedule 09.07.2013


Ответы (4)


Вы также можете преобразовать его вручную:

ObjectId convertedId = new ObjectId(bigInteger.toString(16));
Query query = new Query(Criteria.where("_id").is(convertedId));
person Maciej Walkowiak    schedule 12.07.2013

Вероятно, вы захотите написать собственный преобразователь Spring BigInteger => ObjectId и ObjectId => BigInteger.

См. документацию здесь: http://static.springsource.org/spring-data/data-document/docs/current/reference/html/#d0e2670

------ОБНОВЛЕНИЕ------

Кажется, такой конвертер уже существует в библиотеке Spring-Data-MongoDB: http://static.springsource.org/spring-data/data-document/docs/1.0.0.M1/api/org/springframework/data/document/mongodb/SimpleMongoConverter.ObjectIdToBigIntegerConverter.html

Так что вам просто нужно указать это в конфигурации Spring.

person Mik378    schedule 08.07.2013
comment
Легче сказать, чем сделать :-). Я нашел этот класс в документации к версии 1.0 Spring Data. Но я не зря упомянул версию данных Spring - насколько я вижу, в 1.2 такого конвертера нет. - person Aleksandr Kravets; 09.07.2013

В качестве альтернативы вы можете добавить поле «id» в свои классы коллекций или, возможно, в базовый класс и аннотировать его с помощью org.springframework.data.annotation.Id, как показано ниже:

import org.springframework.data.annotation.Id;

public abstract class BaseDocument {

    @Id
    protected long id;

Это позволит вам выполнять запросы вида:

public boolean doesDocumentExist(Class clazz, long documentId) {
    Query queryCriteria = new Query(Criteria.where("id").is(documentId));
    return mongoTemplate.count(queryCriteria, clazz) == 1;
}

Аннотирование вашего собственного поля id с помощью '@Id' сохранит ваш id как mongo objectId, что избавит вас от самостоятельного преобразования.

person Trevor Gowing    schedule 09.07.2013
comment
Вы получаете что-то не так. У меня есть поле @Id в поле BigInteger в моей сущности. И Spring Data действительно сохраняет этот BigInt как ObjectId. Но... Проблема не в сохранении, а в передаче значения в Query. - person Aleksandr Kravets; 09.07.2013
comment
@AleksandrKravets Хорошо, тогда все, что вам нужно сделать в вашем запросе, это заменить «_id» на любое имя вашего аннотированного идентификатора поля: т. Е. Если ваше поле идентификатора называется id, как в моем примере, просто измените свои критерии следующим образом: Criteria.where (идентификатор) .is (идентификатор) - person Trevor Gowing; 09.07.2013
comment
Нет, не сработало. Как я уже упоминал в вопросе, проблема не в имени поля. Это тип значения и отсутствие автоматического преобразования. - person Aleksandr Kravets; 09.07.2013
comment
Я нахожу это удивительным, поскольку код, который я разместил, взят прямо из моей кодовой базы, которая работает как шарм. Должно быть что-то еще. Мне жаль, что я не смог больше помочь. - person Trevor Gowing; 09.07.2013
comment
Он должен работать. Я читал аналогичную информацию о SO и других ресурсах. Насколько я понимаю, Spring Data использует id как своего рода псевдоним _id. По некоторым данным в определенных версиях SDM работает везде кроме обновления. Опять же, моя проблема не в имени поля. - person Aleksandr Kravets; 09.07.2013

Вы можете преобразовать BigIngeter в ObjectId, используя шестнадцатеричное представление BigInteger. Однако предполагается, что ObjectId имеет длину ровно 24 символа, и синтаксический анализ более короткой строки не удастся выполнить в Java. Таким образом, лучше убедиться, что шестнадцатеричное представление правильно дополнено 0:

String hexString24 = StringUtils.leftPad(bigInteger.toString(16), 24, "0");
ObjectId convertedId = new ObjectId(hexString24);
Query query = new Query(Criteria.where("_id").is(convertedId));
person GaspardP    schedule 01.10.2017