Reputation: 1447
I know two separate APIs in MongoTemplate
, if you want to perform an .aggregate
:
MongoTemplate
, like MongoTemplate.aggregate()
getCollection()
, like MongoTemplate.getCollection().aggregate()
If I run a query and try to map (decode/deserialize/convert) its result to my POJO:
MongoTemplate.aggregate()
works without additional configMongoTemplate.getCollection().aggregate()
requires to specifically use a withCodecRegistry
:CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
);
mongoTemplate
.getCollection("myCollectionName")
.withCodecRegistry(pojoCodecRegistry)
.aggregate(myAggregation, MyPojo.class)
.into(new ArrayList<>());
If I don't use the withCodecRegistry
and I need to map result to my type (e.g. MyPojo.class
) instead of Document.class
, then I get an error saying codec for the class cannot be found or similar.
Example:
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for CodecCacheKey{clazz=class com.example.MyPojo, types=null}.
I need to use MongoTemplate.getCollection().aggregate()
, because it exposes a different set of APIs.
How can I make this work on the general case (so for any POJO I might supply) without specifying withCodecRegistry
every time (so a global config somewhere)?
I'm using this together with SpringBoot
.
Upvotes: 1
Views: 86
Reputation: 1372
If you do not want to create pojoCodecRegistry
and register it .withCodecRegistry(pojoCodecRegistry)
each time you call MongoTemplate.getCollection().aggregate()
,
then you can define the following bean:
@Configuration
public class MongoConfig {
@Bean
public MongoClientSettingsBuilderCustomizer mongoClientCustomizer() {
var pojoCodecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
);
return builder -> builder.codecRegistry(pojoCodecRegistry);
}
}
After this your code to call aggregate will look like this:
mongoTemplate
.getCollection("myCollectionName")
.aggregate(pipeline, MyPojo.class)
.into(new ArrayList<>());
The solution is inspired by https://github.com/spring-projects/spring-boot/issues/20195
Upvotes: 1