MongoDB.live, free & fully virtual. Register Now MongoDB.live, free & fully virtual. Register Now

Unmanaged Object with Embedded Object

I am not able to update an existing object (as an in memory object) that contains an embedded object. Maybe in-memory copies are not compatible with embedded objects or I’m overlooking something.

Using the classes from the documentation here, I have an existing business with a List of embedded addresses. When making an in memory copy of the business, changing the name property and then attempting to save it, Realm throws an error:

Cannot add an existing managed embedded object to a List.

Which is not at all what’s being done. Here’s the code

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)
}

If I remove the embedded List property from the Business class, it works correctly.

macOS 10.15
Realm 10.1.1
XCode 12
No sync - local only

Hi @Jay,
In your code you’re trying to add a new Business in the realm.
Instead you could try this snippet:

// You have the object already so you don't need a copy
let b = realm.objects(Business.self).first! 
try! realm.write {
    b.name = "New Business Name"
}

Please let me know if it helps.

Thanks for the reply @Pavel_Yakimenko

We’re not trying to add a new business, we are modifying the embedded object that is part of an existing business (it’s already saved and managed by Realm)

For our use case, we need a copy. It’s a macOS app with a sheet that pulls down to allow editing of the object and we need an in-memory copy so we can change it around before the user saves it. e.g. the user can click cancel on the sheet and the object is deallocated and no changes are saved.

In this case I’d recommend to create a copy of EmbeddedObject too.
Business(value: b) creates a shallow copy so you need to copy Address models.

    let someBusiness = Business(value: b)
    let addr = Address(value: b.addresses.first!)
    someBusiness.name = "New Business Name"
    someBusiness.addresses.replace(index: 0, object: addr)
    try! realm.write {
       realm.add(someBusiness, update: .modified)
    }

@Jay, as soon as your original code is correct, there is the ticket created to fix this issue.


Thank you for the information provided.