Skip to content

Swift mutable structs applyTODb throws cannotRelateToUnsavedEntities #69

Open
@funcJeff

Description

@funcJeff

Describe the bug
applyToDb throws cannotRelateToUnsavedEntities(message: "Must put the entity before you can apply().") with mutable structs in Swift. Classes work just fine with code sequence.

Basic info:

  • ObjectBox version: 1.7.0
  • Reproducibility: always
  • Device: iPhone 13 mini simulator
  • OS: iOS 16.0

To Reproduce

Classes work:

class FC: Entity, Identifiable, CustomStringConvertible {
    var id: Id = 0
    var name = "none"
    // objectbox: backlink = "f"
    var ns: ToMany<NC> = nil
    required init() {}
    var description: String {
        return "FC: id = \(id); name = \(name); ns = \(ns)"
    }
}

class NC : Entity, Identifiable, CustomStringConvertible {
    var id: Id = 0
    var name = "none"
    var f: ToOne<FC> = nil
    required init() {}
    var description: String {
        return "NC: id = \(id); name = \(name); f = \(f)"
    }
}

    func test4mini() throws { // This works.
        let path = NSTemporaryDirectory() + "/d2"
        let store = try Store(directoryPath: path)
        let fBox = store.box(for: FC.self)
        let nBox = store.box(for: NC.self)
        try fBox.removeAll()
        try nBox.removeAll()
        let f0 = FC()
        f0.name = "X"
        try fBox.put(f0)
        let n0 = NC()
        n0.name = "Y"
        f0.ns.append(n0)
        try f0.ns.applyToDb()
        print("f0 = \(f0)")
        print("n0 = \(n0)")
        print("n0.f = \(n0.f)")
    }

The output is:

f0 = FC: id = 2; name = X; ns = [NC: id = 2; name = Y; f = ToOne(FC: id = 2; name = X; ns = (unresolved))]
n0 = NC: id = 2; name = Y; f = ToOne(FC: id = 2; name = X; ns = (unresolved))
n0.f = ToOne(FC: id = 2; name = X; ns = (unresolved))

That is, the backlink to the ToOne relations works when appending to the ToMany relationship.

This does NOT work:

struct F2: Entity, Identifiable {
    var id: Id
    var name: String
    // objectbox: backlink = "f"
    var ns: ToMany<N2>
}
struct N2: Entity, Identifiable {
    var id: Id
    var name: String
    var f: ToOne<F2>
}

   func test2bmini() throws {
        let path = NSTemporaryDirectory() + "/dy"
        let store = try Store(directoryPath: path)
        let fBox = store.box(for: F2.self)
        let nBox = store.box(for: N2.self)
        try fBox.removeAll()
        try nBox.removeAll()
        var f0 = F2(id: 0, name: "X", ns: nil)
        try fBox.put(&f0)
        var n0 = try nBox.put(struct: N2(id: 0, name: "Y", f: nil))
        try nBox.put(&n0)
        f0.ns.append(n0)
        try fBox.put(&f0, mode: .update)
        try nBox.put(&n0, mode: .update)
        try f0.ns.applyToDb()
        print("f0 = \(f0)")
        print("n0 = \(n0)")
        print("n0.f = \(n0.f)")
    }

The output is:

cannotRelateToUnsavedEntities(message: "Must put the entity before you can apply().")

Expected behavior
Running applyToDb on a ToMany relationship when both values have been put should not result in errors.

Code
See above.

Logs, stack traces
See above.

Additional context

Did you find any workarounds to prevent the issue?
No.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions