[JAVA-5276] Ability to configure BsonConfiguration for default KotlinSerializerCodecProvider Created: 28/Dec/23  Updated: 31/Jan/24  Resolved: 31/Jan/24

Status: Closed
Project: Java Driver
Component/s: Kotlin
Affects Version/s: None
Fix Version/s: 5.0.0

Type: Question Priority: Unknown
Reporter: Jun Tomioka Assignee: Ross Lawley
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Documentation Changes: Not Needed
Documentation Changes Summary:

1. What would you like to communicate to the user about this feature?
2. Would you like the user to see examples of the syntax and/or executable code and its output?
3. Which versions of the driver/connector does this apply to?


 Description   

When I follow this article to configure the driver with kotlinx-serialization integration, it creates `KotlinSerializerCodecProvider` by default (code) and there's no way to configure BsonConfiguration (code1, code2).

 

We are planning to migrate the kotlin mongo library from KMongo to the kotlin driver, and we need to configure BsonConfiguration because the `classDiscriminator` was `___type` and now its `_t` for the BsonConfiguration default instance.

 

We can work around this situation by manually ignoring KotlinCodecProvier while building MongoClientSettings, but it's better if we can configure the default BsonConfiguration directly.



 Comments   
Comment by Githook User [ 24/Jan/24 ]

Author:

{'name': 'Ross Lawley', 'email': 'ross@mongodb.com', 'username': 'rozza'}

Message: Simplify customization of bson-kotlinx (#1293)

Allow configuration to be set on the KotlinSerializerCodecProvider

JAVA-5276
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/baebf9074c69300f7bd70abcd93802d2eaa0766f

Comment by Ross Lawley [ 10/Jan/24 ]

HI jun.tomioka@wolt.com,

A few of the codecs / codec providers can be optionally configured but it must be explicitly set. I think this can be closed as "works as designed".

However, there is no reason why KotlinSerializerCodecProvider cannot have a constructor to allow for easier customization for users that want to explicitly configure their codec registry.

Ross

Comment by Jun Tomioka [ 05/Jan/24 ]

Hi Ross,

Thanks for the explanation. Sounds like putting `MyKotlinSerializerCodecProvider` like this would change the precedence of the providers.

 

val registry = CodecRegistries.fromRegistries(
  CodecRegistries.fromProviders(
    MyKotlinSerializerCodecProvider(BsonConfiguration(classDiscriminator = "__type"))),
    MongoClientSettings.getDefaultCodecRegistry()
  )
)

 

 

If we need to use Kotlin codec with customized BsonConfiguration without changing the precedence, we can't use MongoClientSettings.getDefaultCodecRegistry().

We can work around this by manually listing up the default codec providers except for KotlinCodecProvider, but it'd be great if there's an easy way to do this. It's a feature request, not a blocker.

val registry = CodecRegistries.fromProviders(
  BsonValueCodecProvider(),
  DBRefCodecProvider(),
  DBObjectCodecProvider(),
  ...,
  Jep395RecordCodecProvider(),
 
  // Exclude this to use MyKotlinCodecProvider()
  // KotlinCodecProvider(),
 
  MyKotlinSerializerCodecProvider(BsonConfiguration(classDiscriminator = "___type")),
)

 

Btw, thanks for all the help.

Comment by Ross Lawley [ 04/Jan/24 ]

Hi jun.tomioka@wolt.com,

Thats correct order is important, the codec registry will use the first available codec so by putting the MyKotlinSerializerCodecProvider before the default provider it will be used instead. Note: the KotlinSerializerCodec.create method ensures that only classes annotated with Serializable annotation return a codec.

If further customization is required the MyKotlinSerializerCodecProvider could be limited further by only supporting specific classes or you could register specific codecs as shown in the Customize the Serializer Configuration section.

Ross

Comment by Jun Tomioka [ 04/Jan/24 ]

Hi, ross@mongodb.com 

 

Thanks for the suggestion. Looks like this suggested snippet changes the order of kotlinx-related codec - KotlinCodecProvider is the last one in the default codec, but we put MyKotlinSerializerCodecProvider at the beginning of the providers list. Does this order matter?

```

val registry = CodecRegistries.fromRegistries(
CodecRegistries.fromProviders(
    MyKotlinSerializerCodecProvider(BsonConfiguration(classDiscriminator = "__type"))), 
    MongoClientSettings.getDefaultCodecRegistry())

```

Comment by Ross Lawley [ 03/Jan/24 ]

Hi jun.tomioka@wolt.com,

There is no way to change the default KotlinSerializerCodecProvider however, you can register your own provider like so:

public class MyKotlinSerializerCodecProvider(private val bsonConfiguration: BsonConfiguration) : CodecProvider {
 
    override fun <T : Any> get(clazz: Class<T>, registry: CodecRegistry): Codec<T>? =
        KotlinSerializerCodec.create(clazz.kotlin, bsonConfiguration=bsonConfiguration)
}
 
val registry = CodecRegistries.fromRegistries(
CodecRegistries.fromProviders(
    MyKotlinSerializerCodecProvider(BsonConfiguration(classDiscriminator = "__type"))), 
    MongoClientSettings.getDefaultCodecRegistry())

Then use that registry with the MongoClient/Database/Collection.

I hope that helps,

Ross

Comment by PM Bot [ 28/Dec/23 ]

Hi jun.tomioka@wolt.com, thank you for reporting this issue! The team will look into it and get back to you soon.

Generated at Thu Feb 08 09:04:10 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.