hey guys, I meet a problem when insert a data clas...
# ktor
k
hey guys, I meet a problem when insert a data class into the mongodb collection, this is my model
Copy code
data class User(
    @BsonId
    val id: ObjectId,
    val name: String,
    val age: Int
) {
    override fun toString(): String {
        return "User(id=${id}, name=${name}, age=${age})"
    }
}
and this is revalent code
Copy code
class UserService(val database: MongoDatabase) {
    val users = database.getCollection("users", User::class.java)

    fun insertOne(name: String, age: Int): User {
        val user = User(
            id = ObjectId(),
            name = name,
            age = age
        )

        users.insertOne(user)
        return user
    }
}
and the error is
Copy code
Can't find a codec for CodecCacheKey{clazz=class com.steiner.model.User, types=null}.
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for CodecCacheKey{clazz=class com.steiner.model.User, types=null}.
so can you tell me how to insert a custom class into collection ?
m
this seems to be a MongoDB-specific issue. Have you looked at https://www.mongodb.com/docs/drivers/kotlin/coroutine/current/fundamentals/data-formats/codecs/ yet?
k
ok. let's me check it
by the way, can kotlinx.serialization solve it ?
m
that should be a straightforward implementation for the
Codec
. There might even be an existing one in https://github.com/ltj/bson4k
k
and the example of writing codec is too simple, it is just about boolean type but not class, can you give me an example ?
m
They also have a custom
MonolightCodec
in the examples which encodes a class. Personally I've never used any of these libraries so I can't say more than that 😉
k
indeed, i have never used bson before, I think it is about key-value type, right? if I am right, how to write a key, and how to write the value ? that is the main problem 😋
m
I'm not sure that it necessarily cares about key-value types only. It's just a binary-optimized version of a format like JSON. But in JSON one can encode other values, too. I.e.
true
,
1.23
or
"foobar"
are all valid JSON values, even if they don't make up a full JSON object.
k
thanks for you patience, I have found the answer, for key, just write
writeName
is ok
m
since bson4k can encode any object that supports Kotlin Serialization, I'd probably start looking there to serialize a
data class
k
wtf, still error ?
m
that's unexpected - the new codec registry seems to be missing the default Java standard library encoders? 😖 I'm pretty certain that these should be available from the start...
you might want to try sth like this
Copy code
val newRegistry = CodecRegistries.fromRegistries(
    CodecRegistries.fromCodecs(MyEnumCodec()),
    MongoClientSettings.getDefaultCodecRegistry()
)
k
eh, still the same, but i found that there is no problem with insert, but
findMany
Copy code
fun findMany(name: String? = null, age: Int? = null): List<User> {
        val queryParams = mutableListOf<Bson>()

        if (name != null) {
            queryParams.add(Filters.eq(User::name.name, name))
        }

        if (age != null) {
            queryParams.add(Filters.eq(User::age.name, age))
        }

        return users.find(Filters.and(queryParams)).toList()
    }
and the error is the same
😵‍💫 1
m
you might have more luck in some MongoDB-specific community...
k
thanks
oh, I find the solution, i forget to add this default registry
MongoClientSettings.getDefaultCodecRegistry()
🙌 1
but that follow another problem, I have follow the tutorial, but nothing
ok, I fix it, finally
🦜 2