dartflutter-testobjectboxdata-access-objectflutter-objectbox

Applying changes of ToMany<E> relation to objectbox store in dart


In project i use latest Dart version with objectbox: ^1.0.0:

@Entity
class Node{

 ...
  @Transient()
  final List<Edge> _edges = List<Edge>.empty(growable: true);
 
  final relEdges = ToMany<Edge>();
 ...

}

@Entity
class Edge{
 ...

  @Transient()
  final List<Node> _nodes = List<Node>.empty(growable: true);

  @Backlink()
  final relNodes = ToMany<Node>();
 ...
}

after nodes and edges are created. Nodes are assigned to the list of nodes in edge object(reverse in nodeObject) and then in DAO layer they are (re)applied to relList(ToMany) of objectbox.

Actual put:

main_test.dart:

 // nodes and edge are created
 node1.dao.create(node1);
 node2.dao.create(node2);
 node3.dao.create(node3);
 edge..nodes.addAll([node1,node2]);
 edge.dao.create(edge);
 node1.dao.update(node1..edges.add(edge));
 node2.dao.update(node2..edges.add(edge));
 ...
 // removes edge from node2's edge list
 node2..edges.removeWhere((element) {
  return element.uuid == edge.uuid;
 });
 node3..edges.add(edge);
 // this placement also didn't change anything
 //await node2.dao.update(node2);
 //await node3.dao.update(node3);
 // or remove(1) and add(node3)
 edge..edges.clear();
 edge..edges.addAll([node1,node3]);

 await node2.dao.update(node2);
 await node3.dao.update(node3);
 await node1.dao.update(node1);
 await edge.dao.update(edge)
 ...

edgeDao.dart

    ...
    element.relNodes.clear();
    element.relNodes.addAll(edges);
    ...

nodeDao.dart

    ...
    element.relEdges.clear();
    element.relEdges.addAll(nodes);
    ...

databaseConnector.dart:

 // Box<(Element)> _box; is alrady initialized
 ...
 // it is implemented the same way, for Edge class
 // create works the same way
 Future<void> update(Node element) async {
    this._box.put(element);
  }
 ...

add operation works properly, just like update, before i try to save changes of edge relations, after old node is removed from ToMany and new one is added (this crashes every further put operation). I get following error from objectbox (x3):

>package:objectbox/src/native/bindings/helpers.dart 78:9                                                        ObjectBoxNativeError.throwMapped
>package:objectbox/src/native/bindings/helpers.dart 50:48                                                       throwLatestNativeError
>package:objectbox/src/native/bindings/helpers.dart 17:5                                                        checkObx
>package:objectbox/src/native/box.dart 461:7                                                                    InternalBoxAccess.relRemove
>package:objectbox/src/relations/to_many.dart 195:33                                                            ToMany.applyToDb.<fn>
>dart:collection                                                                                                _LinkedHashMapMixin.forEach
>package:objectbox/src/relations/to_many.dart 168:15                                                            ToMany.applyToDb
>package:objectbox/src/native/box.dart 365:13                                                                   Box._putToManyRelFields.<fn>
>dart:collection                                                                                                _LinkedHashMapMixin.forEach
>package:objectbox/src/native/box.dart 362:37                                                                   Box._putToManyRelFields
> ...

>ObjectBoxException: 404 404: Unknown native error

neither put() nor applyToDB() work. I even tried to use clear() and then to addAll to ToMany from list object. Any suggestions why this happens?


Solution

  • In my case after remove, i have to update the ToMany relation. Only then i can add a new value. When i find the reason, why it these operations don't work in my tests, i'll update the answer.