Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 653
Rodrigo Costa Avatar asked Aug 14 '18 17:08

Rodrigo Costa


People also ask

What is TypeConverter in Android?

Use type converters You support custom types by providing type converters, which are methods that tell Room how to convert custom types to and from known types that Room can persist. You identify type converters by using the @TypeConverter annotation.

How does room work android?

Room autogenerates implementations of your @Database and @Dao annotated classes the first time you compile your code after creating a Room Database. The implementation of UserDatabase and UserDao in the preceding example is generated automatically by the Room annotation processor.


1 Answers

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)
    }
}
like image 154
José Fernando Garcia Junior Avatar answered Oct 17 '22 18:10

José Fernando Garcia Junior