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

如何在ObjectBox @Entity中无需关联存储嵌套对象/嵌套对象列表

问题描述

我尝试对API返回的模型进行本地缓存,模型定义如下:

data class Subject(
    val id: Long,
    val meanings: List<Meaning>
    // 其他无关字段已省略
) 

data class Meaning(
    val meaning: String,
    val primary: Boolean,
    val acceptedAnswer: Boolean
)

Meaning模型仅包含ObjectBox支持的类型,且每个Subject的Meaning都是唯一的,不会在多个Subject间共享。核心需求是:每次从API获取更新数据并覆盖现有Subject时,同时覆盖所有嵌套对象,将Subject及其内部所有嵌套对象视为一个整体。

尝试使用ObjectBox关联定义实体:

@Entity
data class SubjectEntity(
    @Id var id: Long = 0,
    @Index
    @Unique(onConflict = ConflictStrategy.REPLACE)
    var apiId: Long = 0,
) {
    lateinit var meanings: ToMany<MeaningEntity>
}

@Entity
data class MeaningEntity(
    @Id var id: Long = 0,
    val meaning: String = "",
    val primary: Boolean = false,
    val acceptedAnswer: Boolean = false
)

更新时执行以下代码:

subjectEntity.meanings.apply {
    clear()
    addAll(...)
}

subjectBox.put(subjectEntity)

但会导致MeaningEntity盒子中保留之前的所有meanings,必须手动删除旧对象,操作繁琐。关联方式相当于额外维护一张表,不符合ObjectBox作为NoSQL数据库的使用预期,想知道有没有更好的实现方式?

解决方案

使用ObjectBox的**嵌入对象(Embedded Objects)**特性,完全符合你的需求——把嵌套对象和主实体视为一个整体,更新主实体时自动同步嵌套对象的增删改,无需手动维护关联关系。

1. 定义嵌入实体

将Meaning定义为嵌入类,用@Embed标注;在SubjectEntity中用@EmbeddedList标注嵌套列表:

@Entity
data class SubjectEntity(
    @Id var id: Long = 0,
    @Index
    @Unique(onConflict = ConflictStrategy.REPLACE)
    var apiId: Long = 0,
    // 用EmbeddedList标注嵌套的Meaning列表
    @EmbeddedList
    var meanings: List<MeaningEmbed> = emptyList()
)

// 用@Embed标注嵌入类,无需@Entity和@Id
@Embed
data class MeaningEmbed(
    val meaning: String = "",
    val primary: Boolean = false,
    val acceptedAnswer: Boolean = false
)

2. 更新操作

直接将API返回的Subject转换为SubjectEntity后调用put即可,ObjectBox会自动处理嵌套列表的覆盖:

// 假设从API获取到subject: Subject
val subjectEntity = SubjectEntity(
    apiId = subject.id,
    meanings = subject.meanings.map { 
        MeaningEmbed(it.meaning, it.primary, it.acceptedAnswer) 
    }
)

subjectBox.put(subjectEntity)

适配优势

  • 嵌入对象与主实体存储在一起,不存在独立的"表",完全契合你将Subject和Meaning视为整体的需求;
  • 更新主实体时,ObjectBox会自动替换整个嵌套列表,旧的嵌入对象会被直接清除,无需手动删除;
  • 嵌入对象的查询与主实体绑定,不需要额外处理关联查询逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:27:40