You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Hive:同一HiveObject实例无法存入不同Box的问题求助

错误原因与解决方案:The same instance of an HiveObject cannot be stored in two different boxes

错误原因

每个继承自HiveObject的实例,内部都会维护与所属Box的关联(通过_box和_key私有字段)。Hive的设计规则不允许同一个HiveObject实例同时属于两个不同的Box,因此直接将原支出记录实例添加到另一个Box时会触发该错误。

解决方案

核心思路是复制原对象的属性创建新实例,将新实例存入删除记录Box,而非直接移动原实例。具体修改如下:

修改删除函数

将原代码中直接添加原实例的逻辑,替换为创建新实例并复制属性:

ondelete: () {
  // 创建新的ExpenseModel实例,复制原记录的所有属性
  final deletedExp = ExpenseModel(
    title: exp.title,
    category: exp.category, // 若CategoryModel也是HiveObject,需同样创建新实例复制属性
    amount: exp.amount,
    isexpense: exp.isexpense,
  );
  
  final rcyclebox = Boxes.getDeletedRecords();
  rcyclebox.add(deletedExp);
  
  exp.delete();
},

优化:添加对象复制方法

如果需要频繁复制对象,可以给ExpenseModel添加一个copy方法,提升代码复用性:

@HiveType(typeId: 1)
class ExpenseModel extends HiveObject {
  @HiveField(0)
  String title;
  @HiveField(1)
  CategoryModel category;
  @HiveField(2)
  int amount;
  @HiveField(3)
  bool isexpense;

  ExpenseModel({required this.title, required this.category, required this.amount, required this.isexpense});

  // 添加复制方法
  ExpenseModel copy() {
    return ExpenseModel(
      title: title,
      category: category.copy(), // 若CategoryModel是HiveObject,需为它也实现copy方法
      amount: amount,
      isexpense: isexpense,
    );
  }
}

此时删除函数可简化为:

ondelete: () {
  final deletedExp = exp.copy();
  Boxes.getDeletedRecords().add(deletedExp);
  exp.delete();
},

注意事项

如果CategoryModel同样继承了HiveObject,必须为它也实现属性复制逻辑,避免出现相同的跨Box存储错误。

内容的提问来源于stack exchange,提问作者Irfan Ganatra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:40:27