Flutter ObjectBox无法生成含自定义类的数据库模型问题
ObjectBox多实体关联构建报错解决方法
问题背景
跟随《NoSQL Database Storage | Flutter ObjectBox (vs Sqlite, Sqflite, Hive)》视频搭建多类ObjectBox数据库时,添加Set实体关联Exercise后,执行flutter pub run build_runner build出现两个报错:
- Cannot use the default constructor of 'Set': don't know how to initialize param exercise - no such property.
- [WARNING] objectbox_generator:resolver on lib/models/set.dart: skipping property 'exercise' in entity 'Set', as it has an unsupported type: 'Exercise?'
单独存在Exercise类时构建正常,添加关联属性后失败,尝试修改构造参数默认值和const构造未解决。
错误原因
ObjectBox不允许直接将实体类作为属性存储,必须通过**ToOne/ToMany关系注解**定义实体间的关联逻辑,直接用Exercise?作为属性不符合映射规则。
修改后的代码
Exercise.dart
import 'package:objectbox/objectbox.dart'; import 'set.dart'; @Entity() @Sync() class Exercise { int? id; final String? name; final String? target; final String? bodyPart; final String? equipment; final String? gifUrl; // 反向关联:一个Exercise对应多个Set final sets = ToMany<Set>(); Exercise({ this.id = 0, required this.name, required this.target, required this.bodyPart, required this.equipment, required this.gifUrl, }); factory Exercise.fromJson(Map<String, dynamic> json) { return Exercise( id: int.tryParse(json['id'].toString()), name: json["name"].toString(), target: json["target"].toString(), bodyPart: json["bodyPart"].toString(), equipment: json["equipment"].toString(), gifUrl: json["gifUrl"].toString()); } }
Set.dart
import 'package:objectbox/objectbox.dart'; import 'exercise.dart'; @Entity() @Sync() class Set { int? id; final int? repetitions; // 关联Exercise的ToOne关系 final exercise = ToOne<Exercise>(); Set({ this.id = 0, required Exercise exercise, required this.repetitions, }) { this.exercise.target = exercise; } // 可选:支持通过Exercise ID构造的工厂方法 factory Set.withExerciseId({int? id, required int exerciseId, required int? repetitions}) { final set = Set(id: id, exercise: Exercise(name: "", target: "", bodyPart: "", equipment: "", gifUrl: ""), repetitions: repetitions); set.exercise.targetId = exerciseId; return set; } }
关键修改说明
- Exercise类:添加
ToMany<Set>类型的sets属性,用于管理该Exercise对应的所有Set实例,实现反向关联。 - Set类:用
ToOne<Exercise>替代原Exercise?属性,通过target(传入实体对象)或targetId(传入实体ID)完成关联初始化。 - 构造函数中手动初始化关系属性,确保ObjectBox能正确识别关联逻辑。
重新构建命令
修改完成后执行以下命令生成模型:
flutter pub run build_runner build --delete-conflicting-outputs
内容的提问来源于stack exchange,提问作者Ali Haidar
相关产品推荐
相关产品推荐

