Litote / kmongo

[deprecated] KMongo - a Kotlin toolkit for Mongo

Home Page:https://litote.org/kmongo/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Filtering for enum with custom value fails with Jackson serialization

Xfel opened this issue · comments

coll.find(Stop::type eq  StopType.STATION).toList()

where StopType is annotated to use int values:

enum class StopType(@JsonValue val value: Int) {
    STATION(1),
    // ...
}

gives exception:

Exception in thread "main" org.bson.BsonInvalidOperationException: readString can only be called when CurrentBSONType is STRING, not when CurrentBSONType is INT32.
	at org.bson.AbstractBsonReader.verifyBSONType(AbstractBsonReader.java:689)
	at org.bson.AbstractBsonReader.checkPreconditions(AbstractBsonReader.java:721)
	at org.bson.AbstractBsonReader.readString(AbstractBsonReader.java:456)
	at org.litote.kmongo.jackson.JacksonCodec.encode(JacksonCodec.kt:199)
	at com.mongodb.client.model.BuildersHelper.encodeValue(BuildersHelper.java:37)
	at com.mongodb.client.model.Filters$SimpleEncodingFilter.toBsonDocument(Filters.java:1190)
	at com.mongodb.internal.operation.Operations.createFindOperation(Operations.java:175)
	at com.mongodb.internal.operation.Operations.find(Operations.java:163)
	at com.mongodb.internal.operation.SyncOperations.find(SyncOperations.java:99)
	at com.mongodb.client.internal.FindIterableImpl.asReadOperation(FindIterableImpl.java:249)
	at com.mongodb.client.internal.FindIterableImpl.asReadOperation(FindIterableImpl.java:41)
	at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:135)
	at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:92)
	at kotlin.collections.KMongoIterableKt.kCursor(KMongoIterable.kt:43)
	at kotlin.collections.KMongoIterableKt.useCursor(KMongoIterable.kt:49)
	at kotlin.collections.KMongoIterableKt.toList(KMongoIterable.kt:559)
	at QueryTestKt.main(QueryTest.kt:14)

As a workaround I suggest you use a custom serializer

HTH

That does not help.

Using a serializer:

class StopTypeSerializer : JsonSerializer<StopType>() {
    override fun serialize(value: StopType, gen: JsonGenerator, serializers: SerializerProvider?) {
        gen.writeNumber(value.value)
    }
}

I get:

Exception in thread "main" java.lang.IllegalArgumentException: state should be: length >= 5
	at org.bson.assertions.Assertions.isTrueArgument(Assertions.java:62)
	at org.bson.RawBsonDocument.<init>(RawBsonDocument.java:110)
	at org.bson.RawBsonDocument.<init>(RawBsonDocument.java:92)
	at org.litote.kmongo.jackson.JacksonCodec.encode(JacksonCodec.kt:188)

When adding a specific format visitor to the serializer:

    override fun acceptJsonFormatVisitor(visitor: JsonFormatVisitorWrapper, type: JavaType?) {
        visitor.expectIntegerFormat(type)
    }

I instead get:

Exception in thread "main" org.bson.BsonInvalidOperationException: readInt64 can only be called when CurrentBSONType is INT64, not when CurrentBSONType is INT32.
	at org.bson.AbstractBsonReader.verifyBSONType(AbstractBsonReader.java:689)
	at org.bson.AbstractBsonReader.checkPreconditions(AbstractBsonReader.java:721)
	at org.bson.AbstractBsonReader.readInt64(AbstractBsonReader.java:372)
	at org.litote.kmongo.jackson.JacksonCodec.encode(JacksonCodec.kt:195)

Even if I add a toLong() in the serializer, the error stays the same.

Second workaround (without serializer) - tested ;)

col.find(Stop::type from StopType.STATION.value).toList()

Type checking is bypassed

fixed in next release