Room Database技术问题:嵌入含ArrayList字段的对象模型时字段保存报错的解决方法
解决Room嵌入对象中ArrayList字段的类型转换问题
这个问题我之前也碰到过,核心原因是Room不会自动识别嵌入对象(Embedded)内部字段上标注的@TypeConverters注解,你把转换器注解加在LocationModel的coordinates字段上,Room无法感知到这个配置,所以才会抛出无法保存该字段的错误。下面给你几个可行的解决方案:
方案1:在@Embedded字段上添加@TypeConverters
直接把转换器注解移到UserModel里的location字段上,让Room处理这个嵌入对象时应用指定的转换器:
@Entity(tableName = "user_table") class UserModel : Serializable { @PrimaryKey @NonNull var userId: String = "" @Embedded @TypeConverters(ConvertersDAO::class) // 移到这里 var location: LocationModel = LocationModel() // ...其他字段 } data class LocationModel( var city : String = "", var province : String = "", var coordinates : ArrayList<Double> = ArrayList() // 去掉这里的@TypeConverters )
方案2:全局配置转换器(推荐)
如果你的App里多个实体或嵌入对象都需要用到同一个类型转换器,可以把@TypeConverters直接标注在Room的Database类上,让所有操作都共享这个转换器:
@Database(entities = [UserModel::class], version = 1) @TypeConverters(ConvertersDAO::class) // 全局生效 abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao }
这种方式最省心,不需要在每个嵌入对象或实体上单独配置。
方案3:在嵌入对象类上添加@TypeConverters
也可以直接把转换器注解标注在LocationModel类本身,这样只要这个类被嵌入或作为实体使用,都会自动应用转换器:
@TypeConverters(ConvertersDAO::class) // 标注在类上 data class LocationModel( var city : String = "", var province : String = "", var coordinates : ArrayList<Double> = ArrayList() )
额外小建议
在Kotlin里,更推荐用不可变的List<Double>代替ArrayList<Double>,不仅符合语言习惯,也能避免一些意外的修改问题,你的转换器只需要把类型改成List<Double>即可:
class ConvertersDAO { @TypeConverter fun fromStringDouble(value: String?): List<Double>? { val listType: Type = object : TypeToken<List<Double>>() {}.type return Gson().fromJson(value, listType) } @TypeConverter fun fromListDouble(list: List<Double>?): String? { val gson = Gson() return gson.toJson(list) } }
内容的提问来源于stack exchange,提问作者Lộc Trần Phước
相关产品推荐
相关产品推荐

