Realm Kotlin中嵌套对象的忽略属性变更失效问题排查
Realm Kotlin中关联RealmObject的@Ignored属性赋值丢失问题
问题重现
我在使用Realm Kotlin时遇到了一个问题:给关联的RealmObject的@Ignored属性赋值后,值会丢失,只有外部对象的@Ignored属性能保留变更。
数据模型代码
class OuterObject() : RealmObject { @PrimaryKey var _id: RealmUUID = RealmUUID.random() var innerObj: InnerObject? = null @Ignored var ignoredObj: NormalObject? = null } class InnerObject() : RealmObject { @PrimaryKey var _id: RealmUUID = RealmUUID.random() @Ignored var ignoredObj: NormalObject? = null } class NormalObject(var name: String = "")
测试代码及现象
调用函数为两个对象的ignoredObj赋值后,只有外部对象的变更生效:
fun applyIgnoredProperties(outerObj: OuterObject) { outerObj.ignoredObj = NormalObject("Test1") outerObj.innerObj?.ignoredObj = NormalObject("Test2") } fun main() { val outerObj = OuterObject().apply { innerObj = InnerObject() } applyIgnoredProperties(outerObj) println(outerObj.ignoredObj?.name) // 输出 "Test1" println(outerObj.innerObj?.ignoredObj?.name) // 输出 null }
即使将InnerObject改为EmbeddedRealmObject,问题依然存在;但移除所有Realm继承后,代码能正常运行。
原因分析
这是因为RealmObject本质是代理对象,每次访问关联对象(比如outerObj.innerObj)时,Realm都会从数据库重新生成一个新的代理实例。而@Ignored注解的属性不会被持久化到数据库,所以每次获取新的代理实例时,这些属性都会被重置为默认值(null)。你之前给innerObj的ignoredObj赋值的是旧代理实例,后续访问拿到的是新实例,自然看不到赋值结果。
解决方案
使用realm.copyFromRealm()方法将Realm代理对象复制为普通Kotlin对象,同时指定depth参数复制关联对象(depth=1u表示复制外部对象及其直接关联的innerObj)。复制后的对象不再是代理,修改@Ignored属性的值会被正常保留:
.map { it.list.map { obj -> realm.copyFromRealm(obj, 1u) } }
内容的提问来源于stack exchange,提问作者Trent Meyer
相关产品推荐
相关产品推荐

