Search code examples
androidkotlinandroid-roomtypeconverter

error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. in my app?


I am developing news app and I am getting following error error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. private final yodgorbek.komilov.musobaqayangiliklari.model.Source source = null;

below my SportNewsDatabase.kt class where I have implemented database

@Database(entities = [Article::class], version = 1, exportSchema = false)
abstract class SportNewsDatabase : RoomDatabase() {

    abstract fun sportNewsDao(): SportNewsDao

    companion object {
        private var instance: SportNewsDatabase? = null
        fun getInstance( context: Context): SportNewsDatabase? {
            if (instance == null) {
                synchronized(SportNewsDatabase::class.java) {
                    instance = Room.databaseBuilder(context.applicationContext, SportNewsDatabase::class.java, "article_database")
                        .fallbackToDestructiveMigration()
                        .build()
                }
            }
            return instance
        }
    }


}

below SportNewsDao.kt

interface SportNewsDao {

    @Query("SELECT * FROM  article")
    fun getAllData(): LiveData<List<Article>>

    @Insert
    suspend fun addAll(article: List<Article>)


    @Update
    suspend fun updateArticle(article: Article)

    @Delete
    suspend fun deleteArticle(article: Article)

}

below Article.kt

@Entity(tableName = "article")

    data class Article(
        @ColumnInfo(name = "author") val author: String,
        val content: String,
        val description: String,
        var publishedAt: String,
        val source: Source,
        val title: String,
        val url: String,
        val urlToImage: String
    )

below Source.kt

data class Source(
    val id: Any?,
    val name: String
) {

}

below SourceTypeConverters.kt where I am trying to make conversion

object SourceTypeConverters {
    @TypeConverter
    fun ConvertSource(source: Source?): String? {
        return source?.toString()
    }

    @TypeConverter
    fun ConvertSource(source: String?): Source? {
        return source?.let { Source(it) }
    }
}

I want to know where I am making mistake what I have to do in order to avoid error in my app.


Solution

  • The typeConvertor seems to be a bit off. Instead of object let it be a class. Store in DB as JSON string and retrieve it ( GSON library optional).

    class SourceTypeConverter {
        @TypeConverter
        fun fromSource(source: Source): String {
            return JSONObject().apply { 
                put("id", source.id)
                put("name", source.name)
            }.toString()
        }
    
        @TypeConverter
        fun toSource(source: String): Source {
            val json = JSONObject(source)
            return Source(json.get("id"), json.getString("name"))
        }
    }
    

    Now register this TypeConvertor to the Database with annotation TypeConverter.

    @Database(entities = [Article::class], version = 1, exportSchema = false)
    @TypeConverters(SourceTypeConverter::class)
    abstract class SportNewsDatabase : RoomDatabase() {
          /* your code here */
    }