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

Hive报错:'Null'无法转换为'String'类型的问题求助

问题描述

我在学习Hive时,基于教程和示例代码做了修改。原代码运行正常,我在Person模型中新增了一个必填的surname字段:

@HiveType(typeId: 1)
class Person {
  @HiveField(0)
  final String name;

  @HiveField(1)
  final String country;

  @HiveField(2)
  final String surname; // 新增实验字段

  Person({
    required this.name,
    required this.country,
    required this.surname, // 新增实验字段
  });
}

执行生成命令:

dart run build_runner build --delete-conflicting-outputs

运行应用时出现错误:

E/flutter (26138): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'String' in type cast
E/flutter (26138): #0      PersonAdapter.read (package:enemies_list/models/person.g.dart:22:26)
E/flutter (26138): #1      BinaryReaderImpl.read (package:hive/src/binary/binary_reader_impl.dart:328:33)
E/flutter (26138): #2      BinaryReaderImpl.readFrame (package:hive/src/binary/binary_reader_impl.dart:276:26)
E/flutter (26138): #3      FrameHelper.framesFromBytes (package:hive/src/binary/frame_helper.dart:21:26)
E/flutter (26138): #4      FrameIoHelper.framesFromFile (package:hive/src/io/frame_io_helper.dart:42:12)
E/flutter (26138): <asynchronous suspension>
E/flutter (26138): #5      StorageBackendVm.initialize (package:hive/src/backend/vm/storage_backend_vm.dart:86:11)
E/flutter (26138): <asynchronous suspension>
E/flutter (26138): #6      HiveImpl._openBox (package:hive/src/hive_impl.dart:111:9)
E/flutter (26138): <asynchronous suspension>
E/flutter (26138): #7      HiveImpl.openBox (package:hive/src/hive_impl.dart:142:12)
E/flutter (26138): <asynchronous suspension>
E/flutter (26138): #8      main (package:enemies_list/main.dart:13:3)
E/flutter (26138): <asynchronous suspension>

我已经修改了所有需要新增该字段的文件,仅新增一个字段却报错,请问原因是什么?


问题原因及解决办法

核心原因

你的Hive盒子中已经存储了旧版本的Person数据(没有surname字段),新增必填的surname字段后,Hive读取旧数据时该字段的值为Null,但模型要求它是必填的非空String,类型转换失败触发报错。

解决办法

  1. 清空旧数据:卸载应用后重新安装,或者直接删除Hive的存储文件(Android路径为/data/data/你的包名/files/hive/,iOS在应用沙盒的Documents目录下)。
  2. 兼容旧数据:若需要保留旧数据,可修改模型让surname字段可空,或给它设置默认值:
    // 方案1:改为可空类型
    @HiveField(2)
    final String? surname;
    
    // 方案2:设置默认值
    @HiveField(2)
    final String surname; 
    Person({
      required this.name,
      required this.country,
      String? surname,
    }) : surname = surname ?? '';
    
    修改后重新执行dart run build_runner build --delete-conflicting-outputs生成新的适配器文件。
  3. 规范版本迁移:如果需要更严谨的版本管理,可给模型设置adapterVersion,并在打开盒子时添加迁移逻辑:
    @HiveType(typeId: 1, adapterVersion: 2) // 升级版本号
    class Person {
      // ...字段定义
    }
    
    打开盒子时处理版本差异:
    await Hive.openBox<Person>('persons', migration: (oldBox, newBox) {
      if (oldBox.adapterVersion < 2) {
        for (var key in oldBox.keys) {
          var oldPerson = oldBox.get(key);
          newBox.put(key, Person(
            name: oldPerson.name,
            country: oldPerson.country,
            surname: '', // 给旧数据补充默认值
          ));
        }
      }
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 15:07:24