嵌套对象上的领域属性更改被忽略

huangapple go评论71阅读模式
英文:

Realm property changes ignored on embedded objects

问题

我认为我的问题是对 Realm Kotlin 的工作方式有基本的误解。

在我的模式中,有一个包含与另一个 RealmObject 的 To-One 关系的外部 RealmObject。举例来说,每个都包含一个引用普通 Kotlin 类的 ignored property,看起来像这样:

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 = "")

然后,我将一个从 Realm 检索到的 OuterObject 实例传递给某个函数。该函数为外部和内部对象的 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
}

如在两个 println 调用的注释中所示,访问外部被忽略的对象的名称返回实际值,而尝试在内部被忽略的对象上执行相同操作只返回 null。这是因为内部对象上的 ignoredObj 本身仍然为 null。

如果从所有这些中删除 Realm 继承关系,那么代码将按预期工作。我尝试过将 InnerObject 设为 EmbeddedRealmObject,但没有任何区别。我在这里漏掉了什么?非常感谢任何指导。

编辑

Alex的答案将我引向了正确的方向。我决定在查询本身中直接复制所有对象。为 "depth" 参数提供一个值使 OuterObject.innerObj 可以实际使用。

.map {
    it.list.map { obj ->
        realm.copyFromRealm(obj, 1u)
    }
}
英文:

I believe my issue is a fundamental misunderstanding of how Realm Kotlin works.

In my schema there is an outer RealmObject that contains a To-One relationship to another RealmObject. For example-sake, each of these contains an ignored property that references a normal Kotlin class. It looks something like this:

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 = "")

I then pass an instance of the OuterObject (that was retrieved from Realm) into some function. This function assigns a value to the ignoredObj property of both the outer and inner object. After the function completes, only the changes to the outer object seem to be kept.

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
}

As seen in the comments on the two println calls, accessing the name for the outer ignored object returns the actual value, while trying to do the same on the inner ignored object just gives null. This is because the ignoredObj itself it still null on the inner object.

If you remove the Realm inheritance from all of this, then the code works as expected. I've tried having the InnerObject be an EmbeddedRealmObject, didn't make a difference. What am I missing here? Any guidance is much appreciated.

EDIT

Alex's answer pointed me in the right direction. I decided to just hard copy all objects in the query itself. Providing a value for the "depth" param makes OuterObject.innerObj actually use-able.

.map {
    it.list.map { obj ->
        realm.copyFromRealm(obj, 1u)
    }
}

答案1

得分: 1

OuterObject 中的 innerObj 属性是一个领域对象,因此对其忽略的属性所做的更改不会被持久化。当您访问 outerObj.innerObj?.ignoredObj?.name 时,它返回 null,因为忽略的属性从未在数据库中持久化或设置。

如果您希望将 InnerObject 的忽略属性更改持久化,您需要确保它是一个受管领域对象,例如:

val innerObject = realm.copyFromRealm(outerObj.innerObj)
innerObject?.ignoredObj = NormalObject("Test2")
outerObj.innerObj = innerObject
英文:

innerObj property in OuterObject is a realm object, so changes made to its ignored property wont be persisted. when you access outerObj.innerObj?.ignoredObj?.name it returns null because the ignored prop was never persisted in the db or set

if you want changes to the ignored property of InnerObject to be persiseted, you need to make sure it's a managed realm object for example

val innerObject = realm.copyFromRealm(outerObj.innerObj)
innerObject?.ignoredObj = NormalObject("Test2")
outerObj.innerObj = innerObject

huangapple
  • 本文由 发表于 2023年7月7日 04:48:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76632448.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定