We are getting an error attempting to use an embedded object twice - within the same object.
Can’t set link to existing managed embedded object
So here’s a quick example
class PersonClass: Object {
@objc dynamic var name = ""
@obc dynamic var default_address: EmbeddedAddress!
let addressList = List<EmbeddedAddress>()
}
class EmbeddedAddress: EmbeddedObject {
@objc dynamic var state = ""
}
A person class, with no addresses, is created and written to realm
We then want to update the person by adding an address to the address list and then setting one of them as the default address
let addr = EmbeddedAddress()
addr.state = "Florida"
let jay = realm.objects(PersonClass.self).filter("name == 'Jay'").first!
try! realm.write {
jay.addressList.append(addr)
jay.default_address = addr
}
and then running throws an error
Can’t set link to existing managed embedded object
Likewise, if we change the write around to populate the default_address first
Yes, this is expected - embedded objects can only have one parent - for a non-intuitive definition of “parent”. In your case, it may seem like the parent is the same, but the property path is also considered part of the parent information. To try and give you an analogy - top-level objects are serialized to json with their ids (that can be either the primary key or an internal id). Embedded objects are serialized in their entirety. So if you have the following structure:
Even though default_address and addresses[0] contain the same information, they can’t inherently be regarded as the same object. In that sense, they are similar to complex value types at least when it comes to persistence. We were considering automatically creating a copy of the object if you tried to assign it to a property, but decided against it because we thought it wouldn’t be obvious to a developer that those are now different objects.
Interesting - thanks for the very clear explanation.
It would be great if the docs were updated to more clearly state what you answer states as it really makes it obvious these are discreet objects that cannot be referenced. And the bit about the “parent” object not actually being the parent object due to the path constraints is really good info.