I'm using Spring Data MongoDB to manage the communication with MongoDB instance. I have a simple document class containing id and Instant fields:
@Document
data class Test(
@MongoId(FieldType.STRING)
override var id: UUID,
override val updatedAt: Instant,
)
An instance of this document is serialized into Mongo as (or actually showed in the Mongo shell as)
{
_id: '7ea1a5ff-0c3c-451f-9ebd-99def53541f5',
updatedAt: ISODate('2023-10-09T11:43:51.152Z'),
}
When used in the Spring app the deserialization works without issues. However, for testing purposes, I would also like to read documents from stored JSON files. The JSON serialization looks like this:
{
"_id": "c11f01c3-24a8-4321-a0ce-beb041207e5b",
"updatedAt": {
"$date": "2024-03-04T13:53:01.658Z"
},
}
I'm using the Spring-configured ObjectMapper instance for deserializing this (I assume the same instance that is used in the app), so I would expect that everything works as expected. However, apparently the ObjectMapper isn't aware of the MongoDB-specifics so the deserialization fails with
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.time.Instant` from Object value (token `JsonToken.START_OBJECT`)
How to configure the ObjectMapper to properly handle MongoDB dates/times?
Note: The exact way how I'm reading the test data is this:
@Bean
fun repositoryPopulator(objectMapper: ObjectMapper) =
Jackson2RepositoryPopulatorFactoryBean().apply {
setMapper(objectMapper)
setResources(paths)
}
This is in a config class imported into @SpringBootTest so that's why I assume that the ObjectMapper instance should be the same as in the main app. But apparently it isn't.
So, the solution is that you have to add the following annotation over your
Testclass propertyupdatedAtAfter that the following code will work:
The output of this will be:
The
InstantHolderclass that I used is a very simple one:So this provides a solution. But I can offer you a slight optimization where you don't have to instantiate and configure
ObjectMapperclass. Consider the client code like this:This will work exactly the same. However, you can see here the use of static methods of class
JsonUtils. This class is a thin wrapper over ObjectMapper class and it comes as part of MgntUtils Open source library (written and maintained by me). Here is Javadoc for JsonUtils class. The library can be obtained as a Maven artifact from Maven central or from Github as a jar file as well as Javadoc and source code