0
votes

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.

1
It is not a proper way to work with the database. You should create another table for Source and use foreign key constraints. But if you want to use type converter convert it to JSON and retrieve it with gson converter.mmdreza baqalpour

1 Answers

5
votes

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 */
}