Skip to content

Commit 3e9e7f7

Browse files
authored
support to-one relation cycles (#264)
1 parent 9569c75 commit 3e9e7f7

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

objectbox/lib/src/native/box.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,15 @@ class Box<T> {
166166
throw StateError(
167167
'Invalid state: can only use _put() on an entity with relations when executing from inside a write transaction.');
168168
}
169-
if (_hasToOneRelations) _putToOneRelFields(object, mode, tx);
169+
if (_hasToOneRelations) {
170+
// In this case, there may be relation cycles so get the ID first.
171+
if ((_entity.getId(object) ?? 0) == 0) {
172+
final newId = C.box_id_for_put(_cBox, 0);
173+
if (newId == 0) throwLatestNativeError(context: 'id-for-put failed');
174+
_entity.setId(object, newId);
175+
}
176+
_putToOneRelFields(object, mode, tx);
177+
}
170178
}
171179
_builder.fbb.reset();
172180
var id = _entity.objectToFB(object, _builder.fbb);

objectbox/test/relations_test.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,18 @@ void main() {
464464
final read = box.get(1)!;
465465
root.expectSameAs(read);
466466
});
467+
468+
test('cycles', () {
469+
final a = RelatedEntityA();
470+
final b = RelatedEntityB();
471+
a.relB.target = b;
472+
b.relA.target = a;
473+
env.store.box<RelatedEntityA>().put(a);
474+
475+
final readB = env.store.box<RelatedEntityB>().get(b.id!)!;
476+
expect(a.relB.targetId, readB.id!);
477+
expect(readB.relA.target!.id, a.id);
478+
});
467479
}
468480

469481
int toInt(dynamic e) => e.tInt as int;

0 commit comments

Comments
 (0)