Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CoroutineCollection#save doesn't use specified Serializer (kotlinx.serialization) #365

Closed
emmaboecker opened this issue Aug 15, 2022 · 1 comment
Labels

Comments

@emmaboecker
Copy link

I have this data class in my Project:

@Serializable
data class DBPlayer(
    @SerialName("_id") val uuid: SerializableUUID,
    @Contextual val team: Id<DBTeam>?
)

SerializableUUID is a typealias for UUID with my own Serializer:

typealias SerializableUUID = @Serializable(UUIDSerializer::class) UUID

object UUIDSerializer : KSerializer<UUID> {
    override val descriptor: SerialDescriptor =
        PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)

    override fun deserialize(decoder: Decoder): UUID {
        return UUID.fromString(decoder.decodeString())
    }

    override fun serialize(encoder: Encoder, value: UUID) {
        encoder.encodeString(value.toString())
    }
}

When I now try to save an instance of DBPlayer like this, playerCollection being a CoroutineCollection

val player = DBPlayer(owner, team.teamId)
playerCollection.save(player)

It will use the internal UUIDSerializer of KMongo and not the one that I specified.

But when I use insertOne this is not the case:

val player = DBPlayer(owner, team.teamId)
database.playerCollection.insertOne(player)

Furthermore, I'm having to call UUID#toString because it would otherwise try to use the internal Serializer again and not be able to find the right document

val player = DBPlayer(owner, team.teamId)
plugin.database.playerCollection.updateOneById(owner.toString(), player)

Is this intentional behavior, or is this a bug? Because it seems rather inconsistent.

@zigzago
Copy link
Member

zigzago commented Aug 20, 2022

The typealias trick will not work. The way to go is to use registerSerializer, but I think it will not work for built-in type below. I will provide a fix in next kmongo release.

    private val serializersMap: Map<KClass<*>, KSerializer<*>> = mapOf(
        ObjectId::class to ObjectIdSerializer,
        BigDecimal::class to BigDecimalSerializer,
        ByteArray::class to ByteArraySerializer,
        Date::class to DateSerializer,
        Calendar::class to CalendarSerializer,
        GregorianCalendar::class to CalendarSerializer,
        Instant::class to InstantSerializer,
        ZonedDateTime::class to ZonedDateTimeSerializer,
        OffsetDateTime::class to OffsetDateTimeSerializer,
        LocalDate::class to LocalDateSerializer,
        LocalDateTime::class to LocalDateTimeSerializer,
        LocalTime::class to LocalTimeSerializer,
        OffsetTime::class to OffsetTimeSerializer,
        BsonTimestamp::class to BsonTimestampSerializer,
        Locale::class to LocaleSerializer,
        Binary::class to BinarySerializer,
        Id::class to IdSerializer(false),
        StringId::class to IdSerializer(true),
        WrappedObjectId::class to IdSerializer(false),
        Pattern::class to PatternSerializer,
        Regex::class to RegexSerializer,
        UUID::class to UUIDSerializer
    )

@zigzago zigzago added the bug label Sep 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants