just-ai/jaicf-kotlin

Unrecognized field "$oid" (class org.bson.types.ObjectId)

Closed this issue · 3 comments

hram commented

I hawe simple model

data class WordModel(
val word: String,
val length: Int,
val imageUrl: String
)

Whem I add item to MongoBD automaticly added field _id even if I remove this field

{
"_id": {
"$oid": "5ead47f27c213e5d2fa60237"
},
"word": "some_word",
"length": 9,
"imageUrl": "some_url"
}

And then when I try to get data I have an exeption
Unrecognized field "$oid" (class org.bson.types.ObjectId), not marked as ignorable (4 known properties: "machineIdentifier", "counter", "timestamp", "processIdentifier"]) at [Source: (String)"{ "_id" : { "$oid" : "5ea9c2837c213e2096467134" }, "word" : "some_word", "length" : 9, "imageUrl" : "some_url" }"; line: 1, column: 23] (through reference chain: com.justai.jaicf.template.scenario.WordModel["_id"]->org.bson.types.ObjectId["$oid"])

BotContextModel have _id field with type as String https://github.com/just-ai/jaicf-kotlin/blob/master/managers/mongo/src/main/kotlin/com/justai/jaicf/context/manager/mongo/BotContextModel.kt

If I add val _id: String to my model then I have an exeption
Cannot deserialize instance of java.lang.Stringout of START_OBJECT token at [Source: (String)"{ "_id" : { "$oid" : "5ead47f27c213e5d2fa60237" }, "word" : "some_word", "length" : 9, "imageUrl" : "some_url" }"; line: 1, column: 11] (through reference chain: com.justai.jaicf.template.scenario.WordModel["_id"]) com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance ofjava.lang.String out of START_OBJECT token at [Source: (String)"{ "_id" : { "$oid" : "5ead47f27c213e5d2fa60237" }, "word" : "some_word", "length" : 9, "imageUrl" : "some_url" }"; line: 1, column: 11] (through reference chain: com.justai.jaicf.template.scenario.WordModel["_id"])

What am I doing wrong?

@hram Could you please provide a complete source code of your persistence logic? Also note that you have to clean up your database once you've added an _id field.

hram commented

@morfeusys
Model code

data class WordModel(
val word: String,
val length: Int,
val imageUrl: String
)

Manager code

class WordsManager(private val collection: MongoCollection) {

private val mapper = jacksonObjectMapper().enableDefaultTyping()

fun getWords(length: Int): List<WordModel> {
    val list: MutableList<WordModel> = mutableListOf()
    collection.find(Filters.eq("length", length)).forEach { item ->
        val model = mapper.readValue(item.toJson(), WordModel::class.java)
        list.add(model)
    }
    return list
}

}

And test code

internal class WordsManagerTest {

val login = "some_login"

val password = "some_password"

private val uri = MongoClientURI("mongodb://$login:$password@ds055762.mlab.com:55762/heroku_9w2h7mvv")

private val client = MongoClient(uri)

private val manager = WordsManager(client.getDatabase(uri.database!!).getCollection("words"))

@Test
fun getWords() {

    val words = manager.getWords(9)

    assertTrue(words.size == 1)
}

}

In databease I have single collection
изображение

In this collection I have single record
изображение

Record was added from web form. Whel I add new record I do not specify _id field. This field was added automatically.

You have to have _id field in your model class to persist it over mongodb. Please learn more how MongoBotContextManager manages models using Jackson mapper. As I can see, you're trying to load model from mongo collection that contains an _id field that doesn't match to your model. You can declare your _id field as ObjectId instead of String, or remove a document and persist your own that contains String _id fiels.