Kotlin中Android Room一对多关系配置及Gson序列化输出问题
Android Room一对多联查结果Gson序列化格式异常修复方案
问题根源
当前关联类使用@Embedded注解嵌套GramPanchayatSurveyEntity实例,Gson序列化时会将该实例作为独立嵌套对象输出,导致JSON结构多出一层gpSurveyEntity节点,和预期的主表字段与关联数组同层平铺的结构不符。
可选修复方案
方案1:自定义Gson序列化器(无需重复定义字段)
该方案不需要修改现有Room关联类结构,通过自定义序列化规则实现字段平铺:
- 编写对应关联类的序列化适配器
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 } }
- 初始化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
相关产品推荐
相关产品推荐

