Litote/kmongo

When using Jackson as the default object mapping engine, updateMany() doesn't serialize objects properly

rxsto opened this issue · 0 comments

rxsto commented

I am using the fun <T : Any> MongoCollection<T>.updateMany(filter: Bson, vararg updates: SetTo<*>, updateOptions: UpdateOptions = UpdateOptions()): UpdateResult method on version 4.8.0 to update multiple properties at once for many documents that match the filter's criteria.

The updateMany() call in itself works and continues to edit the correct documents in the Mongo cluster, but it avoids serializing values properly. In my example I am trying to update an enum on the entity, which has been set correctly when inserting earlier, but is now being updated to the non-serialized value.

collection
    .updateMany(
        Filters.and(
            Entity::id eq id,
            Entity::property eq property
        ),
        SetTo(
            Entity::name,
            newName
        ),
        SetTo(
            Entity::type,
            Type.NEW_TYPE
        )
    )

The enum Type is being serialized like the following:

enum class Type(@JsonValue val value: Int) {

    DEFAULT_TYPE(0),
    NEW_TYPE(1);

    companion object {
        @JvmStatic
        @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
        fun forType(value: Int): Type? {
            return Type.values().asSequence()
                .firstOrNull { type -> type.value == value }
        }
    }
}

In methods like replaceOne() custom-serializable values are properly edited. We're using the following in a for loop as a workaround:

collection
    .replaceOne(
        Entity::id eq entry.id,
        entry,
        ReplaceOptions().upsert(true)
    )

Is there something we are missing, or is this a bug? We would expect the updateMany() call to behave the same in regards to serialization.

~ Cheers