Customizing MapCodec

I have a POJO, one field of which is a Map<String, Object>. At least one of these Objects is an Instant. POJO writes correctly to Mongo, a DATETIME field is written. When reading back however, it decodes into a java.util.Date because of the default type mappings applied to the MapCodec. I understand its possible to supply my own copy BsonTypeClassMap with overrides, but is that feasible in practice?

Normally, I construct my CodecRegistries as follows:

CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
…custom codecs/providers for my classes,
PojoCodecProvider.builder()
.register([custom class models])
.conventions(conventions)
.automatic(true)
.build());

Given that the mongo default set of codecs are constructed without my custom type map, I don’t see any feasible way to set the map later. Is my only option to copy the code out of the driver into my own configuration class so that I can send in my custom type mappings at construction time?

It’s tricky, but I think I have a solution:

        ClassModelBuilder<TestPojo> classModelBuilder = ClassModel.builder(TestPojo.class);
        var propertyBuilder = classModelBuilder.getProperty("extraFields");
        @SuppressWarnings("rawtypes")
        Codec mapCodec = new MapCodec(MongoClientSettings.getDefaultCodecRegistry(),
                new BsonTypeClassMap(Map.of(BsonType.DATE_TIME, Instant.class)));
        propertyBuilder.codec(mapCodec);
        var registry = CodecRegistries.fromProviders(
                MongoClientSettings.getDefaultCodecRegistry(),
                PojoCodecProvider.builder()
                        .automatic(true)
                        .register(classModelBuilder.build())
                        .build());

Interesting…so build up my classmodel/propertymodel by hand so that I can apply a custom instance of mapcodec with my specific type overrides. Am I correct in believing that those overrides are scoped to just the single classmodel then? Thats great for this use case if so.
If, however, I wanted to globally override and not have to handbuild each classmodel, I assume this wouldn’t be possible (short of copying the code from the driver).

Thanks!

Ken

Yes, these overrides are scoped to just that single property model on the single class model. If you want to overided this globally, it’s more straightforward. Something like should do it:

        var bsonTypeClassMap = new BsonTypeClassMap(Map.of(BsonType.DATE_TIME, Instant.class));
        var registry = CodecRegistries.fromProviders(
                new MapCodecProvider(bsonTypeClassMap),
                new DocumentCodecProvider(bsonTypeClassMap),
                MongoClientSettings.getDefaultCodecRegistry(),
                PojoCodecProvider.builder()
                        .automatic(true)
                        .build());

Jeff