You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin中为Realm添加嵌入式对象并作为托管对象使用?

问题

现有如下简化代码:

// 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 // 无效果
    println(bar.isManaged().toString()) // 输出 false
}

其中Foo是RealmObject(父对象),Bar是EmbeddedRealmObject。

当前bar对象并未转为托管对象,因此添加后对它的操作仅针对普通Kotlin对象,不会写入Realm。需要解决的是:如何将bar转为托管对象以正常操作?

Realm文档仅覆盖了同时创建父对象和嵌入式对象的场景(此时可对父对象调用copyToRealm),但当前场景是已有父对象,需为其添加新的嵌入式对象。

另外,更新已有的嵌入式对象可正常工作:

// given foo of type Foo
realm.write {
    val foo = findLatest(frozenFoo)
    requireNotNull(foo)
    bar = foo.bars.firstOrNull{it.barId == 123}
    bar.baz = 456 // 正常生效
    println(bar.isManaged().toString()) // 输出 true
}

对象定义示例:

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

class Bar : EmbeddedRealmObject {
    var barId: Int = 0
    var baz: Int = 0
}
解决方案

要让新创建的Bar嵌入式对象转为托管状态,有两种可行方式:

方式1:添加后从父对象列表中获取托管实例

嵌入式对象只有关联到托管的父对象后才会成为托管对象,因此在foo.bars.add(bar)之后,从foo.bars中取出刚添加的对象,后续操作这个实例即可:

realm.write {
    val foo = findLatest(frozenFoo)
    requireNotNull(foo)
    val bar = Bar().apply{barId = 123}
    foo.bars.add(bar)
    // 从列表中获取刚添加的托管对象
    val managedBar = foo.bars.last()
    managedBar.baz = 456 // 正常生效
    println(managedBar.isManaged().toString()) // 输出 true
}

方式2:直接创建托管的嵌入式对象

利用RealmList的createObject方法,直接在父对象的列表中创建托管的嵌入式对象,无需先创建普通Kotlin对象:

realm.write {
    val foo = findLatest(frozenFoo)
    requireNotNull(foo)
    // 直接在列表中创建托管的Bar对象
    val bar = foo.bars.createObject().apply{barId = 123}
    bar.baz = 456 // 正常生效
    println(bar.isManaged().toString()) // 输出 true
}

也可以用copyToRealm指定父对象和关联字段来创建托管实例:

realm.write {
    val foo = findLatest(frozenFoo)
    requireNotNull(foo)
    val bar = copyToRealm(Bar().apply{barId = 123}, parent = foo, fieldName = "bars")
    bar.baz = 456 // 正常生效
    println(bar.isManaged().toString()) // 输出 true
}

关键原理

嵌入式对象无法独立存在,必须依附于托管的RealmObject父对象。只有当它被关联到托管父对象(如加入父对象的RealmList)后,才会转为托管状态;此时操作原普通Kotlin对象不会同步到Realm,必须操作托管实例。

内容的提问来源于stack exchange,提问作者Adam Burley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:50:12