How to turn room entity to data class in kotlin?

277 Views Asked by At

I'm making a dictianry app and I pull data from json file in my locale asset. I take the data for the first time and when I do, I save it to the room and then I read it from there. But I have a problem. I did type converter for my data model class but I think it wants another type converter. I couldnt understand what I 'm supposed to do. Could you help me to solve this issue ? I am sharing my codes below

DataModel

Word

@JvmInline
@Serializable
value class WordDataModel(
    val allData : List<WordsItem>
)


@Serializable
data class WordsItem(
    val words: List<CommonWords>
) {
    fun toEntity() = CommonWordEntity(
        words = words
    )

}

@Serializable
data class CommonWords(
   val word:String?=null,
   val meaning:String?=null
)

Room

CommonWordEntity

@Entity(tableName = "MostCommonWords")
data class CommonWordEntity(


    @ColumnInfo(name = "commonWords") val words : List<CommonWords>,
    @PrimaryKey(autoGenerate = true) val uid : Int? = null

)

CommonWordDao

@Dao
interface CommonWordDao {

    @Query("SELECT * FROM MostCommonWords")
    suspend fun getAllWords() : List<CommonWordEntity>


    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun initData(word: List<CommonWordEntity> )

}

CommonWordDatabase

@Database(
    entities = [CommonWordEntity::class],
    version = 1
)

@TypeConverters(CommonWordConverter::class)
abstract class CommonWordDatabase: RoomDatabase() {
    abstract val wordDao: CommonWordDao

}

Repositories

WordRepositoryImpl

class WordRepositoryImpl @Inject constructor(
    private val dao: CommonWordDao,
    private val assetDataSource: AssetDataSource
) : WordRepository {


    override suspend fun initData() {

        val wordsList = assetDataSource.getCommonWords().allData
        dao.initData(wordsList.map { it.toEntity() })

    }

    override suspend fun getAllWords() : Flow<List<CommonWords>?> {

        return flow {
            emit(dao.getAllWords()) // The error appears hear
        }

    }


}

WordRepository

interface WordRepository {

    suspend fun initData()
    suspend fun getAllWords() : Flow<List<CommonWords>?>


}

Converter

CommonWordConverter

class CommonWordConverter {

    @TypeConverter
    fun fromSource(ListCommonWords:List<CommonWords>) : String{
        val gson = Gson()
        return gson.toJson(ListCommonWords)
    }

    @TypeConverter
    fun toSource(json: String): List<CommonWords> {
        val gson = Gson()
        val typeToken = object : TypeToken<List<CommonWords>>() {}.type
        return Gson().fromJson(json, typeToken)
    }


}

ERRORS

error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
    private final java.util.List<com.enestigli.dictionaryapp.data.locale.datamodel.CommonWords> words = null;

enter image description here

This error occurs in WordsRepositoryImpl where I specified as a comment line

1

There are 1 best solutions below

0
Steyrix On

Your error is pretty clear.

Your method getAllWords() in dao returns type List<CommonWordEntity>, but your method in WordRepositoryImpl returns flow of type List<CommonWords>?. So you need to somehow fetch common words from common-word entities.

Since every instance of CommonWordEntity contains the list of common words, you can do something like this

override suspend fun getAllWords() : Flow<List<CommonWords>?> {

    return flow {
        emit(
            dao.getAllWords().map { it.words }.flatten()
        )
    }

}

The map here converts your List<CommonWordEntity> to List<List<CommonWords>>, then the flatten merges all lists to one list which is List<CommonWords> - the type that you want to return.