使用Box存储对象数组后查询仅得单个对象的技术求助
问题分析与解决方案
核心原因:对象被覆盖
你遇到的问题本质是所有SaleBookCopy对象在存储时被互相覆盖,最终只剩最后一个。大概率是以下两种情况导致:
- 主键重复:
SaleBookCopy类的@Id主键字段,在所有对象中值相同。ObjectBox的put方法是「插入或更新」逻辑——如果主键已存在,新对象会直接覆盖旧对象。 - 关联字段错误:你查询用的
SaleBookCopy_id并非绑定SaleBook的外键,或者所有对象的该字段值被错误设置为同一个,导致查询结果仅返回一个(但本质还是存储时被覆盖)。
修复步骤
1. 修正实体类定义
先确保SaleBookCopy的主键和关联字段配置正确:
@Entity class SaleBookCopy { @Id var id: Long = 0 // 主键:设为0时ObjectBox会自动分配唯一ID,不要手动给多个对象设相同值 var saleBookId: Long = 0 // 新增字段:绑定所属SaleBook的ID // 你的其他业务字段 }
2. 正确存储关联对象
存储前给每个SaleBookCopy设置对应的SaleBook ID,避免因主键重复被覆盖:
val saleBookCopies: List<SaleBookCopy> = saleBook.book_copies // 给每个副本绑定所属书籍的ID saleBookCopies.forEach { it.saleBookId = saleBook.id } // 批量存储(循环存储效果一致) saleBookCopyBox.put(saleBookCopies)
3. 正确查询所有关联对象
用saleBookId作为查询条件,即可获取当前SaleBook对应的所有副本:
val saleBookCopies = saleBookCopyBox.query() .equal(SaleBookCopy_.saleBookId, saleBook.id) // 使用生成的字段常量,避免拼写错误 .build() .find()
更优雅的关联方式:用ObjectBox注解
直接在SaleBook类中定义@ToMany关联,无需手动查询,直接通过对象获取关联副本:
@Entity class SaleBook { @Id var id: Long = 0 // 定义一对多关联,target指向SaleBookCopy,property绑定对应的外键字段 @ToMany(target = SaleBookCopy::class, property = "saleBookId") lateinit var bookCopies: List<SaleBookCopy> // 其他业务字段 } // 存储时直接保存SaleBook,ObjectBox会自动处理关联的SaleBookCopy saleBookBox.put(saleBook) // 后续获取副本直接调用 val copies = saleBook.bookCopies
验证方法
存储后调用saleBookCopyBox.all()查看所有数据:
- 如果总数为1,说明确实是覆盖问题,检查主键设置;
- 如果总数为30,说明是查询条件错误,核对查询字段与存储时的字段是否一致。
内容的提问来源于stack exchange,提问作者Mwanagenzi
相关产品推荐
相关产品推荐

