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

Room自定义对象列表TypeConverter失效问题求助

问题分析与解决方案

核心问题

错误java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY的本质是:Room在解析查询返回的emaps字段时,误用了单个Emap的TypeConverter去解析JSON数组格式的字符串,导致Gson无法将数组转换为单个对象。

具体修复步骤

1. 移除冲突的TypeConverter方法

你的Converters类同时包含List<Emap>和单个Emap的转换逻辑,这会让Room无法正确判断使用哪一个转换器。保留列表转换方法,移除单个对象的转换逻辑(除非你有单独存储单个Emap的业务需求):

class Converters {
    @TypeConverter
    fun fromEmapListToString(emaps: List<Emap>): String {
        return GsonBuilder().create().toJson(emaps)
    }

    @TypeConverter
    fun fromStringtoEmapList(emapsString: String): List<Emap> {
        val listType = object : TypeToken<List<Emap>>(){}.type
        return GsonBuilder().create().fromJson(emapsString, listType)
    }
}

2. 统一TypeConverter作用范围

避免同时在字段和数据库全局配置转换器,移除UserEmaps实体中emaps字段上的@field:TypeConverters注解,保留Database类上的全局配置即可:

@Entity(tableName = "emaps_users")
data class UserEmaps(
    @PrimaryKey(autoGenerate = false)
    val userId : Int,
    // 移除字段上的TypeConverters注解
    val emaps : List<Emap>
)

3. 优化查询方式(更稳妥的方案)

建议查询完整的UserEmaps实体,再从中提取emaps列表,而不是直接查询单个字段。这样Room会严格按照实体定义的转换器规则处理数据:

@Query("SELECT * FROM emaps_users WHERE userId = :userId LIMIT 1")
suspend fun getUserEmaps(userId : Int) : UserEmaps?

使用时的调用逻辑:

val userEmaps = dao.getUserEmaps(userId)
val emapsList = userEmaps?.emaps ?: emptyList()

4. 升级数据库版本(关键)

由于修改了TypeConverter逻辑,需要升级数据库版本号,确保Room重新处理数据转换规则,避免旧数据解析异常:

@Database(
    entities = [
        User::class,
        Term::class,
        Emap::class,
        Page::class,
        PageIndex::class,
        Incidencia::class,
        Emap.Poi::class,
        UserEmaps::class,
        CuadernoDeViaje::class
    ], 
    version = 3, // 版本号从2升级为3
    exportSchema = false
)
@TypeConverters(Converters::class)
abstract class CanaryDatabase : RoomDatabase()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:53:15