-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Closed
Labels
Description
Goals
Upsert an object that contains an embedded object.
Expected Results
Upsert works flawlessly.
Actual Results
Upsert crashes an app.
2021-03-04 19:48:14.412232+0100 Example[37771:2640657] *** Terminating app due to uncaught exception 'RLMException', reason: 'Cannot set a link to an existing managed embedded object'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff20421af6 __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007fff20177e78 objc_exception_throw + 48
2 Realm 0x0000000103fcddc0 _ZN18RLMAccessorContext12createObjectEP11objc_objectN5realm12CreatePolicyEbNS2_6ObjKeyE + 3568
3 Realm 0x000000010410859e RLMAddObjectToRealm + 302
4 RealmSwift 0x0000000105ad1770 $s10RealmSwift0A0V3add_6updateySo0aB6ObjectC_AC12UpdatePolicyOtF + 1392
…
)
libc++abi.dylib: terminating with uncaught exception of type NSExceptionSteps for others to Reproduce
- Create an instance of Realm database.
- Create an instance of object that contains an embedded object (
MyObject). - Set the embedded object to non-nil.
- Write the instance to the database.
- Create a copy of the first instance.
- Upsert the second instance into the database.
Code Sample
Models:
final class MyEmbeddedObject: EmbeddedObject {
@objc dynamic var value = false
}
final class MyObject: Object {
@objc dynamic var id = ObjectId.generate()
@objc dynamic var embeddedObject: MyEmbeddedObject?
override static func primaryKey() -> String? {
return "id"
}
}Code:
let realm = try! Realm()
let myObject1 = MyObject()
myObject1.embeddedObject = MyEmbeddedObject()
try! realm.write {
realm.add(myObject1)
}
let myObject2 = MyObject(value: myObject1)
try! realm.write {
realm.add(myObject2, update: .modified) // ⚠️ Responsible line
}Code that works, but I guess is a workaround instead of a solution.
try! realm.write {
myObject2.embeddedObject = MyEmbeddedObject(value: myObject2.embeddedObject as Any)
realm.add(myObject2, update: .modified)
}I understand it relates how Object.init(value:) initializer works (shallow instead of deep copy), but as I call Realm.add(_:update:) with .modified instead of .all, I expected this to work properly.
Version of Realm and Tooling
Realm framework version: 10.7.0
Realm Object Server version: N/A
Xcode version: 12.4
iOS/OSX version: 14.4
Dependency manager + version: CocoaPods 1.10.1