#java #spring #mongodb #bulkupdate
#java #spring #mongodb #bulkupdate
Вопрос:
В моем тестовом коде я сначала выполняю обычную upsert с помощью MongoTemplate.upsert(). Он правильно добавляет данные в БД, и в БД появляется следующий документ, как и ожидалось:
{ "_id" : 1, "elements" : [ { "payload" : "payload" } ] }
Затем я выполняю аналогичную upsert с использованием BulkOperations. Сбой происходит со следующим исключением:
org.bson.codecs.configuration.Исключение CodecConfigurationException: не удается найти кодек для элемента класса.
Я думал, что эти два вызова должны выполняться одинаково. Я что-то упускаю в BulkOperations API? Как я могу выполнять массовые операции для кодирования объектов так же, как и обычные операции?
Я использую mongo-java-driver 3.3.0 (аналогичная проблема также может наблюдаться в 2.14.3)
public class Main {
public static void main(String[] args) throws UnknownHostException {
MongoTemplate template = new MongoTemplate(new Mongo("localhost"), "local");
// works
template.upsert(makeQuery(1), makeUpdate(), Data.class);
// fails miserably
BulkOperations ops = template.bulkOps(BulkOperations.BulkMode.UNORDERED, Data.class);
ops.upsert(makeQuery(2), makeUpdate());
ops.execute();
}
private static Query makeQuery(int id) {
return Query.query(Criteria.where("id").is(id));
}
private static Update makeUpdate() {
Update update = new Update();
update.set("elements", Collections.singletonList(new Element()));
return update;
}
}
@Document(collection = "test")
class Data {
private int id = 1;
private List<Element> elements;
}
class Element {
private String payload = "payload";
}
Ответ №1:
Похоже, что в spring-data-mongo есть ошибка при массовом обновлении List
поля, а элемент в List
нем не является скалярным (например String
, Integer
). Он жалуется, что нет codes
.
Есть один способ избежать этого
private static Update makeUpdate() {
Update update = new Update();
update.set("elements", mongoConverter.convertToMongoType(Collections.singletonList(new Element())));
return update;
}
где mongoConverter
a org.springframework.data.mongodb.core.convert.mongoConverter
, и вы можете автоматически подключить экземпляр в вашем компоненте.