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

Kotlin中Android Room一对多关系配置及Gson序列化输出问题

Android Room一对多联查结果Gson序列化格式异常修复方案

问题根源

当前关联类使用@Embedded注解嵌套GramPanchayatSurveyEntity实例,Gson序列化时会将该实例作为独立嵌套对象输出,导致JSON结构多出一层gpSurveyEntity节点,和预期的主表字段与关联数组同层平铺的结构不符。

可选修复方案

方案1:自定义Gson序列化器(无需重复定义字段)

该方案不需要修改现有Room关联类结构,通过自定义序列化规则实现字段平铺:

  1. 编写对应关联类的序列化适配器
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import java.lang.reflect.Type

class GpSurveyRelationSerializer : JsonSerializer<GpSurveyWithImageRelation> {
    override fun serialize(
        src: GpSurveyWithImageRelation,
        typeOfSrc: Type,
        context: JsonSerializationContext
    ): JsonElement {
        val resultJson = JsonObject()
        // 平铺主表实体所有字段到根节点
        src.gpSurveyEntity?.let { survey ->
            context.serialize(survey).asJsonObject.entrySet().forEach { entry ->
                resultJson.add(entry.key, entry.value)
            }
        }
        // 添加关联照片数组字段
        resultJson.add("sPhotoArray", context.serialize(src.sPhotoArray))
        return resultJson
    }
}
  1. 初始化Gson实例时注册该适配器,后续统一用该实例做序列化
val customGson = GsonBuilder()
    .registerTypeAdapter(GpSurveyWithImageRelation::class.java, GpSurveyRelationSerializer())
    .create()

// 序列化查询结果
val targetJson = customGson.toJson(yourQueryResultList)
  • 方案优势:不需要重复定义主表字段,后续主表实体增删字段不需要同步修改关联类,维护成本低

方案2:调整关联类结构(无需自定义Gson规则)

直接将主表所有字段平铺定义在关联类中,Room会自动映射同名字段,序列化后直接得到平铺结构:

import androidx.room.PrimaryKey
import androidx.room.Relation

data class GpSurveyWithImageRelation(
    // 平铺GramPanchayatSurveyEntity所有字段,字段名需和实体类完全一致
    @PrimaryKey
    var gpCode: Int,
    var distCode: Int,
    var locationTypeCode: Int,
    var location: String,
    var latitude: String,
    var longitude: String,
    var googleLocation: String,
    var distanceBtwHeadQrToGp: String,
    var recommendedHeightOfTower: String,
    var BBNL_Exist: String,
    var anyCongestion: String,
    var nearByGpCode: Int,
    var surveyBy: String,
    var surveyAt: String,
    val status: String,

    // 保持原有@Relation关联配置不变
    @Relation(parentColumn = "gpCode", entityColumn = "gpCode")
    var sPhotoArray: List<AddedPhotoEntity>? = null
)
  • 方案优势:不需要额外配置Gson序列化规则,逻辑直观,序列化性能更高
  • 注意事项:主表实体字段变动时需要同步修改关联类的对应字段,避免映射失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:30:54