Невозможно десериализовать localdatetime с помощью mongo и mongojack

У меня есть простой pojo

import lombok.Data;

@Data
public class DataPojo {
   private LocalDateTime myDate;           
}

Когда я пытаюсь прочитать pojo от mongo + mongojack

MongoCredential credential = MongoCredential.createCredential(userName, "aDb", password.toCharArray());
MongoClient mongoClient = new MongoClient(new ServerAddress(mongoServer), Arrays.asList(credential));
DB db = mongoClient.getDB("aDb");
DBCollection aCollection = db.getCollection("aCollection");

JacksonDBCollection<DataPojo, String> jDbCol = JacksonDBCollection.wrap(aCollection, DataPojo.class, String.class);
DataPojo d = jDbCol.findOne();

Я получаю следующую ошибку

java.lang.RuntimeException: IOException encountered while reading from a byte array input stream
at org.mongojack.internal.stream.JacksonDBDecoder.decode(JacksonDBDecoder.java:67)
...
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Problem deserializing property 'myDate' (expected type: [simple type, class java.time.LocalDateTime]; actual type: java.util.Date), problem: argument type mismatch (through reference chain: DataPojo["myDate"])

Я читал кое-что о @JsonDeserialize(using = LocalDateTimeDeserializer.class), и это приводит к другим ошибкам.

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (VALUE_EMBEDDED_OBJECT), expected START_ARRAY: Expected array or string.

Я использую mongo-java-driver версии 3.1.0-rc0, mongojack версии 2.5.1. MongoDB, с которым я работаю, — 2.6.9. Поле, которое я пытаюсь прочитать, является ISODate.

Похоже, моя проблема на уровне драйвера. Есть ли способ указать драйверу монго представлять даты как java.time.LocalDateTime вместо java.util.Date?


person Jeff Benton    schedule 11.12.2015    source источник
comment
Привет. Я никогда раньше не работал с MongoDB или аннотациями Джексона, но всегда хотел. Я потратил секунду, чтобы посмотреть, смогу ли я решить ваш вопрос как есть, и я не смог. На случай, если никто не ответит, не могли бы вы использовать кодек, если аннотаций недостаточно? Я просто не уверен, какова ваша конечная цель: заставить работать аннотации или заставить работать приложение. Я просматривал следующий ресурс на Кодеки и реестры кодеков. Возможно, он сделает то, что вам нужно.   -  person Mike    schedule 11.12.2015
comment
Интересно. Моя главная цель состояла в том, чтобы увидеть, что потребуется для десериализации в объект LocalDateTime. Я предпочитаю придерживаться любой наилучшей практики, чтобы заставить это работать.   -  person Jeff Benton    schedule 11.12.2015
comment
Что касается лучших практик, я понятия не имею о MongoDB. Все, что я понял, это то, что, хотя аннотации могут быть полезными, я считаю, что они могут быть чрезмерно волшебными. Придерживайтесь самого простого и понятного решения, и оно принесет вам больше пользы.   -  person Mike    schedule 11.12.2015


Ответы (1)


Ваша проблема не на уровне драйвера; MongoDB вообще ничего не знает о java.util.Date. Но тип BSON Date почти идентичен java.util.Date во внутреннем представлении. К счастью, в оболочке MongoDB он всегда печатается с использованием часового пояса Z, поэтому не слишком сложно просто игнорировать часовой пояс и вместо этого рассматривать его как java.time.LocalDateTime, но нет встроенного способа сделать это явным на уровне BSON.

На уровне картографа есть несколько различных способов, которыми вы можете указать здесь желаемое сопоставление. Из вашего вопроса неясно, какой LocalDateTimeDeserializer вы пытались использовать; но прежде всего нужно убедиться, что вы используете тот, который предназначен для java.time.LocalDateTime, а не org.joda.time.LocalDateTime. Если вы проверили это и все еще испытываете проблемы, вы можете подумать о написании собственного преобразователя вместо десериализатора, который вы бы вызывали с почти идентичной аннотацией:

@JsonDeserialize(converter = LocalDateTimeConverter.class)

Разница в том, что вам просто нужно реализовать метод преобразования из java.util.Date в org.joda.time.LocalDateTime, а не вообще иметь дело с потоками JSON.

person kdkeck    schedule 22.12.2015