swiftrealmcascading-deletesrealm-listrealm-embedded-object

Realm Swift Error: Cycles containing embedded objects are not currently supported


As the error message in the title states, I have a Realm with nested embedded objects. That is, a parent Object with an EmbeddedObject that contains another EmbeddedObject.

Getting a Realm instance produces the following error:

Schema validation failed due to the following errors:

  • Cycles containing embedded objects are not currently supported: 'ChildObject.children'

Example

Here's an example of what this looks like:

public final class ParentObject: Object {
    @objc dynamic public var primaryKey = ""

    public let children = List<ChildObject>()

    public override class func primaryKey() -> String? {
        "primaryKey"
    }
}

public final class ChildObject: EmbeddedObject {
    public let children = List<ChildObject>()
}

// Getting the default Realm will throw an error.
let _ = try! Realm()

I'm actually using a different EmbeddedObject for ChildObject's children property, but it appears the issue is the same either way.

Question

The reason I attempted this nesting of embedded objects was to avoid having to manage cascading deletes. However, I am currently stuck. Is there a alternative solution to this issue that avoids cascading deletes?

Aside

Encoding ChildObject's children to Data solves this issue, but this approach feels like a hack and is not without other issues.

I'm currently using RealmSwift v10.1.3.


Solution

  • It turns out using a different EmbeddedObject type for the list element of ChildObject’s children property will solve this issue. The solution looks like this:

    final class ChildObject: EmbeddedObject {
        // Use `GrandChildObject` instead of `ChildObject` for `List.Element`.
        let children = List<GrandChildObject>()
    }
    
    final class GrandChildObject: EmbeddedObject {
        // ...
    }
    

    Just make sure to avoid using the same type in GrandChildObject, as it seems to be a limitation of EmbeddedObject. For example, don't do this:

    final class GrandChildObject: EmbeddedObject {
        @objc dynamic var child: GrandChildObject?
    }