Filtering for enum with custom value fails with Jackson serialization
Xfel opened this issue · comments
Felix Treede commented
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)
zigzago commented
As a workaround I suggest you use a custom serializer
HTH
Felix Treede commented
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.
zigzago commented
Second workaround (without serializer) - tested ;)
col.find(Stop::type from StopType.STATION.value).toList()
Type checking is bypassed
zigzago commented
fixed in next release