-
Notifications
You must be signed in to change notification settings - Fork 112
Description
Hi, thanks a lot for mongojack!
We recently upgraded mongojack from 4.2.1 to 4.8.2 and the following construct no longer works:
MongoCollection<Document> collection = mongoDB.getTemplateCollection(Document.class);
collection.aggregate(List.of(new Document("$match", List.of(Filters.and(Filters.eq("a", "b"), Filters.eq("b", "c"))))))
.into(new ArrayList<>());throws a
org.mongojack.MongoJsonMappingException: Error mapping BSON to POJOs
at org.mongojack.internal.stream.JacksonEncoder.encode(JacksonEncoder.java:43)
at org.mongojack.internal.stream.JacksonCodec.encode(JacksonCodec.java:61)
at org.bson.codecs.EncoderContext.encodeWithChildContext(EncoderContext.java:91)
at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:212)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:170)
at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:44)
at org.bson.BsonDocumentWrapper.getUnwrapped(BsonDocumentWrapper.java:199)
at org.bson.BsonDocumentWrapper.containsKey(BsonDocumentWrapper.java:124)
at com.mongodb.client.internal.AggregateIterableImpl.getOutNamespace(AggregateIterableImpl.java:240)
...
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.mongodb.client.model.Filters$AndFilter and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ImmutableCollections$List12[0])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1308)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:414)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:53)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:30)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:479)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:318)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1572)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1061)
at org.mongojack.internal.stream.JacksonEncoder.encode(JacksonEncoder.java:41)
... 84 more
After some investigation, the issue arises because previously, bson 4.3.x serialized Iterables and Maps directly, which was changed for bson 4.4.0 in this PR: mongodb/mongo-java-driver#811
Now, bson delegates serialization of Iterables and Maps to the codecRegistry, which for us is mongojack's JacksonCodecRegistry. But the JacksonCodecRegistry.java:isDefault(Class<T> clazz) function does not list Iterables and Maps as classes that the default registry should handle, so Jackson tries to serialize the List and therefore also the Filters$AndFilter, which results in the changed behavior.
A workaround for us is to override the isDefault function:
pojoCodecRegistry = new JacksonCodecRegistry(mapper, MongoClientSettings.getDefaultCodecRegistry(), null,
UuidRepresentation.STANDARD) {
@Override
protected <T> boolean isDefault(Class<T> clazz) {
if (Iterable.class.isAssignableFrom(clazz) ||
Map.class.isAssignableFrom(clazz)) {
return true;
}
return super.isDefault(clazz);
}
};but maybe you would like to include this in the standard isDefault function.