realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.32k stars 2.15k forks source link

Exception on saving of Unmanaged Object with Embedded Object #6921

Open pavel-ship-it opened 4 years ago

pavel-ship-it commented 4 years ago

Crash during upsert of an existing object with a list of EmbeddedObject inside.

Goals / Expected Results

I can upsert a record.

Actual Results

Exception: Terminating app due to uncaught exception 'RLMException', reason: 'Cannot add an existing managed embedded object to a List.'

Steps for others to Reproduce

Create unmanaged copy of existing object with the property - list of EmbeddedObject's children objects. Try to add it with UpdatePolicy.update

Workaround

Create a deep copy of a target object.

Code Sample

class Address: EmbeddedObject {
    @objc dynamic var street: String? = nil
    @objc dynamic var city: String? = nil
    @objc dynamic var country: String? = nil
    @objc dynamic var postalCode: String? = nil
}

// Define an object with an array of embedded objects
class Business: Object {
    @objc dynamic var _id = ObjectId.generate()
    @objc dynamic var name = ""
    let addresses = List<Address>() // Embed an array of objects

    override static func primaryKey() -> String? {
        return "_id"
    }

    convenience init(name: String, addresses: [Address]) {
        self.init()
        self.name = name
        self.addresses.append(objectsIn: addresses)
    }
}

    let b = realm.objects(Business.self).first!

    //make an unmanaged copy of a business
    let someBusiness = Business(value: b)
    someBusiness.name = "New Business Name"

    try! realm.write {
        realm.add(someBusiness, update: .modified)
    }

Stack trace

*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff2043a126 __exceptionPreprocess + 242
    1   libobjc.A.dylib                     0x00007fff20177f78 objc_exception_throw + 48
    2   delcrash                            0x00000001036918c5 _ZN18RLMAccessorContext12createObjectEP11objc_objectN5realm12CreatePolicyEbNS2_6ObjKeyE + 3125
    3   delcrash                            0x00000001036ea20d RLMAddObjectToRealm + 285
    4   delcrash                            0x00000001038876c4 $s10RealmSwift0A0V3add_6updateySo0aB6ObjectC_AC12UpdatePolicyOtF + 1252
    5   delcrash                            0x00000001034fc24b $s8delcrash14ViewControllerC9addActionyyFyyXEfU_ + 251
    6   delcrash                            0x00000001034fb84f $ss5Error_pIgzo_ytsAA_pIegrzo_TR + 15
    7   delcrash                            0x00000001034fc2a4 $ss5Error_pIgzo_ytsAA_pIegrzo_TRTA.1 + 20
    8   delcrash                            0x00000001038866cb $s10RealmSwift0A0V5write16withoutNotifying_xSaySo20RLMNotificationTokenCG_xyKXEtKlF + 299
    9   delcrash                            0x00000001034fbfb8 $s8delcrash14ViewControllerC9addActionyyF + 1112
    10  delcrash                            0x00000001034fbace $s8delcrash14ViewControllerC6runAddyyF + 46
    11  delcrash                            0x00000001034fb0d3 $s8delcrash14ViewControllerC11viewDidLoadyyF + 723
    12  delcrash                            0x00000001034fba8b $s8delcrash14ViewControllerC11viewDidLoadyyFTo + 43
    13  UIKitCore                           0x00007fff23f37de3 -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 88
    14  UIKitCore                           0x00007fff23f3c6ca -[UIViewController loadViewIfRequired] + 1084
    15  UIKitCore                           0x00007fff23f3cab4 -[UIViewController view] + 27
    16  UIKitCore                           0x00007fff246ac28b -[UIWindow addRootViewControllerViewIfPossible] + 313
    17  UIKitCore                           0x00007fff246ab978 -[UIWindow _updateLayerOrderingAndSetLayerHidden:actionBlock:] + 219
    18  UIKitCore                           0x00007fff246ac93d -[UIWindow _setHidden:forced:] + 362
    19  UIKitCore                           0x00007fff246bf950 -[UIWindow _mainQueue_makeKeyAndVisible] + 42
    20  UIKitCore                           0x00007fff248fa524 -[UIWindowScene _makeKeyAndVisibleIfNeeded] + 202
    21  UIKitCore                           0x00007fff23ace736 +[UIScene _sceneForFBSScene:create:withSession:connectionOptions:] + 1671
    22  UIKitCore                           0x00007fff2466ed47 -[UIApplication _connectUISceneFromFBSScene:transitionContext:] + 1114
    23  UIKitCore                           0x00007fff2466f076 -[UIApplication workspace:didCreateScene:withTransitionContext:completion:] + 289
    24  UIKitCore                           0x00007fff2415dbaf -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] + 358
    25  FrontBoardServices                  0x00007fff25a6a136 -[FBSScene _callOutQueue_agent_didCreateWithTransitionContext:completion:] + 391
    26  FrontBoardServices                  0x00007fff25a92bfd __94-[FBSWorkspaceScenesClient createWithSceneID:groupID:parameters:transitionContext:completion:]_block_invoke.176 + 102
    27  FrontBoardServices                  0x00007fff25a77b91 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 209
    28  FrontBoardServices                  0x00007fff25a928cb __94-[FBSWorkspaceScenesClient createWithSceneID:groupID:parameters:transitionContext:completion:]_block_invoke + 352
    29  libdispatch.dylib                   0x00000001054dfa88 _dispatch_client_callout + 8
    30  libdispatch.dylib                   0x00000001054e29d0 _dispatch_block_invoke_direct + 295
    31  FrontBoardServices                  0x00007fff25ab88f1 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 30
    32  FrontBoardServices                  0x00007fff25ab85d7 -[FBSSerialQueue _targetQueue_performNextIfPossible] + 433
    33  FrontBoardServices                  0x00007fff25ab8a9c -[FBSSerialQueue _performNextFromRunLoopSource] + 22
    34  CoreFoundation                      0x00007fff203a8845 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    35  CoreFoundation                      0x00007fff203a873d __CFRunLoopDoSource0 + 180
    36  CoreFoundation                      0x00007fff203a7c81 __CFRunLoopDoSources0 + 346
    37  CoreFoundation                      0x00007fff203a23f7 __CFRunLoopRun + 878
    38  CoreFoundation                      0x00007fff203a1b9e CFRunLoopRunSpecific + 567
    39  GraphicsServices                    0x00007fff2b793db3 GSEventRunModal + 139
    40  UIKitCore                           0x00007fff2466d40f -[UIApplication _run] + 912
    41  UIKitCore                           0x00007fff24672320 UIApplicationMain + 101
    42  libswiftUIKit.dylib                 0x00007fff53c487b2 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF + 98
    43  delcrash                            0x000000010350100a $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 122
    44  delcrash                            0x0000000103500f7e $s8delcrash11AppDelegateC5$mainyyFZ + 46
    45  delcrash                            0x0000000103501059 main + 41
    46  libdyld.dylib                       0x00007fff20257409 start + 1
    47  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'RLMException', reason: 'Cannot add an existing managed embedded object to a List.'
terminating with uncaught exception of type NSException
CoreSimulator 732.18 - Device: iPhone 8 (A8CA0A6C-C943-4C70-8EC4-EF9FC5E0F5F5) - Runtime: iOS 14.1 (18A8394) - DeviceType: iPhone 8

Version of Realm and Tooling

Realm framework version: 10.1.2 Xcode version: 12 iOS/OSX version: 14 Dependency manager + version: SPM

sipersso commented 3 years ago

I am surprised no one is assigned to this issue. Getting the same problem here. This makes it very inconvenient to work with embedded objects. In my case there are two levels, which makes it even worse. It also differs from the behavior in the Android SDK.

tgoyne commented 2 years ago

This is specifically related to realm.add(), which the Android SDK does not have.

onelogapp commented 2 years ago

Any news on this? I've changed some models to benefit from embedded objects only to have the app crash all over now because of this :/

onelogapp commented 2 years ago

I fixed this in my app by converting the object to a dictionary/json representation and then using that as the parameter for value in let unmanaged = SomeObject(value: objectValue). Would be great if we didn't have to do these workarounds and the SDK would do it on its own

afsmarques commented 2 years ago

@onelogapp so this is a work in progress yet, right? in my case, i get Cannot set a link to an existing managed embedded object when trying to update my Object with an EmbeddedObject field