kotlinrealmrealm-embedded-object

How to add an embedded object to a Realm and then work with it as a managed object in Kotlin?


I have code similar to the following (heavily simplified):

// given foo of type Foo
realm.write {
    val foo = findLatest(frozenFoo)
    requireNotNull(foo)
    bar = Bar().apply{barId = 123}
    foo.bars.add(bar)
    bar.baz = 456 // does nothing
    println(bar.isManaged().toString()) // prints false
}

Here Foo is a RealmObject (parent) and Bar is an EmbeddedRealmObject.

The bar object was not switched to be a managed object, so working with it after writing it was just working with a plain Kotlin object and not written to Realm. How do I change bar into a managed object so I can work with it properly?

In the Realm docs they are only covering cases where you are creating the parent object and the embedded object at the same time, so you call copyToRealm on the parent object. But in my case, I already have a parent object and I'm trying to create a new embedded object to add to that parent.

If I do the same thing with an update to an existing embedded object, it works fine:

// given foo of type Foo
realm.write {
    val foo = findLatest(frozenFoo)
    requireNotNull(foo)
    bar = foo.bars.firstOrNull{it.barId == 123}
    bar.baz = 456 // works fine
    println(bar.isManaged().toString()) // prints true
}

EDIT: As someone asked for the details of the objects. They could be anything, for example:

class Foo : RealmObject {
    @PrimaryKey
    var _id: ObjectId = ObjectId()
    var bars: RealmList<Bar> = realmListOf()
}

class Bar : EmbeddedRealmObject {
    var barId: Int = 0
    var baz: Int = 0
}

Solution

  • As nobody responded on StackOverflow, we reached out to MongoDB consultants and they confirmed that it's not possible to add an embedded object and immediately convert it to be managed. You have to re-query the parent (non-embedded) object from Realm after adding the embedded object, in order to get the managed embedded object.