Flutter结合Equatable与ObjectBox:ToMany关系无法正常更新问题
问题根源
- ToMany关联初始化逻辑被破坏:直接在构造函数中给
Bar.foos赋值会绕过ObjectBox的关联初始化流程。ToMany是ObjectBox维护的特殊代理对象,需要与Box上下文绑定,手动赋值普通List或自定义ToMany实例会导致关联脱离ObjectBox的跟踪,无法同步Foo的更新。 - Flutter端缓存机制限制:ObjectBox的实体实例和关联对象存在内存缓存,即使重新查询Bar,若实例被ObjectBox对象池复用,旧的
ToMany缓存依然有效;且Flutter版未提供Java/Kotlin版的reset()方法手动清除缓存。
最优解决方案
1. 修复关联初始化方式
不要在构造函数中直接传入ToMany<Foo>,让ObjectBox自动初始化关联:
@Entity() class Bar extends Equatable { int id; late final ToMany<Foo> foos; Bar({this.id = 0}); @override List<Object?> get props => [id]; }
添加关联时统一使用bar.foos.add(foo),确保ObjectBox正确维护关联元数据与缓存关联。
2. 手动刷新关联数据的方法
更新Foo后若需立即获取最新关联数据,可通过以下方式绕过缓存:
- 重新查询Foo实例:从Box中获取Foo的最新数据,替代关联中的缓存实例:
// 更新并保存Foo foo.name = "新名称"; boxFoo.put(foo); // 获取Bar后,重新拉取每个Foo的最新数据 final bar = boxBar.get(barId)!; final updatedFoos = bar.foos.map((cachedFoo) => boxFoo.get(cachedFoo.id)!).toList(); - 直接查询关联列表:通过ObjectBox查询获取Bar关联的Foo列表,不依赖
ToMany缓存:// 需确保Foo有反向关联的barId字段(双向关联场景) final updatedFoos = boxFoo.query(Foo_.barId.equals(barId)).build().find();
3. 临时调试方案(不推荐生产用)
若因对象池复用导致旧实例残留,可查询时强制触发磁盘IO获取新实例:
final bar = boxBar.get(barId, allowDiskIO: true)!;
此方式会降低性能,仅用于临时调试验证。
总结
核心问题是构造函数直接赋值ToMany破坏了ObjectBox的关联管理逻辑,正确做法是让ObjectBox自动初始化ToMany,并通过add()维护关联。刷新数据时优先通过重新查询Foo实例或直接查询关联列表的方式绕过缓存,避免依赖ToMany的内存缓存。
内容的提问来源于stack exchange,提问作者ubiquibacon
相关产品推荐
相关产品推荐

