androidandroid-roomobject-composition

Android Room TypeConverter not working


I'm trying to save some data in my Room database but it keeps showhing me an error, here's the code:

MovieDao.kt

@Dao
interface MoviesDao {
    @Query("SELECT * from movie")
    fun getAll() : LiveData<List<Movie>>

    @Update
    fun update(movie: Movie)

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(movie: Movie)
}

MoviesDatabase.kt

@Database(entities = [Movie::class], version = 1, exportSchema = false)
@TypeConverters(TorrentConverter::class, GenreConverter::class)
abstract class MoviesDatabase : RoomDatabase() {
    companion object {
        private var instance: MoviesDatabase? = null
        fun getDatabase(context: Context) : MoviesDatabase{
            if(instance == null) {
                instance = Room.databaseBuilder(context.applicationContext, MoviesDatabase::class.java,
                    "movies_database").build()
            }
            return instance as MoviesDatabase
        }
    }
    abstract fun getMoviesDao() : MoviesDao
}

MovieModels.kt

 @Entity(tableName = "movie")
    data class Movie(
        val url: String,
        @PrimaryKey
        val imdb_code: String,
        val title: String,
        val year: Int,
        val rating: Float,
        val runtime: Int,
        @TypeConverters(GenreConverter::class)
        val genres: List<String>?,
        val synopsis: String,
        val yt_trailer_code: String,
        val language: String,
        val mpa_rating: String,
        val medium_cover_image: String,
        val large_cover_image: String,
        val state: String,
        @TypeConverters(TorrentConverter::class)
        var torrents: List<Torrent>,
        var saved: Boolean = false,
        var marked: Boolean = false
    ) : Serializable

    data class Torrent(
        val url: String,
        val hash: String,
        val quality: String,
        val seeds: Int,
        val peers: Int,
        val size: String,
        val size_bytes: Long
    ) : Serializable

TypeConverters.kt

class TorrentConverter {
    @TypeConverter
    fun toTorrent(json: String): Torrent {
        val type = object : TypeToken<Torrent>() {}.type
        return Gson().fromJson(json, type)
    }

    @TypeConverter
    fun toJson(torrent: Torrent) = Gson().toJson(torrent)
}

class GenreConverter {
    @TypeConverter
    fun toGenre(json: String): List<String> {
        val type = object : TypeToken<List<String>>() {}.type
        return Gson().fromJson(json, type)
    }

    @TypeConverter
    fun toJson(genres: List<String>) = Gson().toJson(genres)
}

the error shows me:

error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. private java.util.List torrents;

Can someone please help me to figure out why is this error happening? Thanks alot.


Solution

  • It's happening because your TorrentConverter is returning and getting the wrong types. The method toTorrent should return a List<Torrent> and the method toJson should receive a List<Torrent> Try this TypeConverter:

    class TorrentConverter {
        @TypeConverter
        fun toTorrent(json: String): List<Torrent> {
            val type = object : TypeToken<List<Torrent>>() {}.type
            return Gson().fromJson(json, type)
        }
    
        @TypeConverter
        fun toJson(torrent: List<Torrent>): String {
            val type = object: TypeToken<List<Torrent>>() {}.type
            return Gson().toJson(torrent, type)
        }
    }