avik
avik

Reputation: 117

Room database table creation error when data class having a inner class

Requirement is to parse json data and insert it into room database using Kotlin.Parsing is done but while creating the table using data class then the problem is arising as the data class have a inner class. Not able to create the table with the fields inside the inner class.

Not able to understand how can i use the @TypeConverters

@Entity(tableName = "tbl_newsData")
@TypeConverters(ReposPersistentConverter::class)
data class Article(
    @PrimaryKey(autoGenerate = true) var _id: Long?,
    @ColumnInfo(name = "author") var author: String?,
    @ColumnInfo(name = "title") var title: String?,
    @ColumnInfo(name = "description") var description: String?,
    @ColumnInfo(name = "url") var url: String?,
    @ColumnInfo(name = "urlToImage") var urlToImage: String?,
    @ColumnInfo(name = "publishedAt") var publishedAt: String?,
    @ColumnInfo(name = "content") var content: String?,
    var source: Source?
){
    constructor() : this(null,"", "", "", "", "",
        "", "", "", "",null)
}

class ReposPersistentConverter {
    val gson = Gson()
    // RepoOwner
    @TypeConverter
    fun storeRepoOwnerToString(data: Source): String = gson.toJson(data)

    @TypeConverter
    fun storeStringToRepoOwner(value: String): Source = gson.fromJson(value)
}

@Entity(tableName = "tbl_newsData")
data class Article(
    @PrimaryKey(autoGenerate = true) var _id: Long?,
    @ColumnInfo(name = "author") var author: String?,
    @ColumnInfo(name = "title") var title: String?,
    @ColumnInfo(name = "description") var description: String?,
    @ColumnInfo(name = "url") var url: String?,
    @ColumnInfo(name = "urlToImage") var urlToImage: String?,
    @ColumnInfo(name = "publishedAt") var publishedAt: String?,
    @ColumnInfo(name = "content") var content: String?,
    var source: Source?  //inner class
){
    constructor() : this(null,"", "", "", "", "",
        "", "", "", "",null)
}

////Source class

data class Source(
    val id: String,
    val name: String
)

//json

{

    "source": {
        "id": null,
        "name": "Geeksofdoom.com"
    },
    "author": "The Movie God",
    "title": "Hulu Comings and Goings: What’s New and What’s Leaving In September 2019",
    "description": "For those of you who do your entertainment streaming on Hulu, whether it be responsibly in moderation or recklessly in full-on binge watching sessions, there's plenty of TV shows and movies arriving and departing each month to keep track of. The titles set to…",
    "url": "https://www.geeksofdoom.com/2019/08/26/hulu-comings-goings-new-leaving-september-2019",
    "urlToImage": "https://www.geeksofdoom.com/GoD/img/2016/02/hulu.jpg",
    "publishedAt": "2019-08-26T18:00:53Z",
    "content": "For those of you who do your entertainment streaming on Hulu, whether it be responsibly in moderation or recklessly in full-on binge watching sessions, there’s plenty of TV shows and movies arriving and departing each month to keep track of.The titles set to … [+8407 chars]"

}

error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. private com.app.newsapp.dashboard.model.Source source;

Upvotes: 2

Views: 373

Answers (1)

androholic
androholic

Reputation: 696

@Entity(tableName = "tbl_newsData")
data class Article(
    @PrimaryKey(autoGenerate = true) var _id: Long?,
    @ColumnInfo(name = "author") var author: String?,
    @ColumnInfo(name = "title") var title: String?,
    @ColumnInfo(name = "description") var description: String?,
    @ColumnInfo(name = "url") var url: String?,
    @ColumnInfo(name = "urlToImage") var urlToImage: String?,
    @ColumnInfo(name = "publishedAt") var publishedAt: String?,
    @ColumnInfo(name = "content") var content: String?,
    @TypeConverters(SourceTypeConverter::class)
    @ColumnInfo(name = "source")
    var source: Source?
){
    class SourceTypeConverter {
        @TypeConverter
        fun fromDeliveryExchangeList(source: Source?): String? {
            if (source == null) {
                return null
            }
            val gson = Gson()
            val type = object : TypeToken<Source>() {

            }.type
            return gson.toJson(source, type)
        }

        @TypeConverter
        fun toDeliveryExchangeList(source: String?): Source? {
            if (source == null) {
                return null
            }
            val gson = Gson()
            val type = object : TypeToken<Source>() {

            }.type
            return gson.fromJson(source, type)
        }
    }

    constructor() : this(null,"", "", "",
        "", "", "", "",null)
}

////////Add the converter

@Database(entities = arrayOf(Article::class), version = 1)
@TypeConverters(Article.SourceTypeConverter::class)
abstract class AppDataBase : RoomDatabase() {
}

Upvotes: 1

Related Questions