The Room library is not recognizing a TypeConverter
I created for a List
of enums. However, when I change this to an ArrayList
of enums it works fine. Anyone has any idea why and what can I do to make this work with List
? (Using List in Kotlin is easier and I really don't wanna be converting back and forwards to ArrayList
just because of this).
Here is my code:
My model:
@Entity
data class Example(@PrimaryKey val id: String?,
val name: String,
var days: List<DayOfWeek>?)
DayOfWeek
is an enum:
enum class DayOfWeek {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY;
val value: Int
get() = ordinal + 1
companion object {
private val ENUMS = DayOfWeek.values()
fun of(dayOfWeek: Int): DayOfWeek {
if (dayOfWeek < 1 || dayOfWeek > 7) {
throw RuntimeException("Invalid value for DayOfWeek: " + dayOfWeek)
}
return ENUMS[dayOfWeek - 1]
}
}
}
My TypeConverter
:
private const val SEPARATOR = ","
class DayOfWeekConverter {
@TypeConverter
fun daysOfWeekToString(daysOfWeek: List<DayOfWeek>?): String? {
return daysOfWeek?.map { it.value }?.joinToString(separator = SEPARATOR)
}
@TypeConverter
fun stringToDaysOfWeek(daysOfWeek: String?): List<DayOfWeek>? {
return daysOfWeek?.split(SEPARATOR)?.map { DayOfWeek.of(it.toInt()) }
}
}
And I set it in my DB class like this:
@Database(entities = arrayOf(Example::class), version = 1)
@TypeConverters(DayOfWeekConverter::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun exampleDao(): ExampleDao
}
My DAO looks like this:
@Dao
interface ExampleDao {
@Query("SELECT * FROM example")
fun getAll(): LiveData<List<Example>>
@Insert(onConflict = REPLACE)
fun save(examples: List<Example>)
}
The error I get with this code is:
error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
e:
e: private java.util.List<? extends com.example.DayOfWeek> days;
Like I said above, if I change the days
property to ArrayList<DayOfWeek>
(and make the changes to ArrayList
in DayOfWeekConverter
) then everything works fine. If anyone can help me figure this out and tell me how I can use List
here it'd be of great help, it is driving me crazy :/.
For some reason, Room does not like Kotlin List
, but when I've replaced List
with MutableList
it started to work:
@Entity
data class Example(@PrimaryKey val id: String,
val name: String,
var days: MutableList<DayOfWeek>?)
class DayOfWeekConverter {
companion object {
@TypeConverter
@JvmStatic
fun daysOfWeekToString(daysOfWeek: MutableList<DayOfWeek>?): String? =
daysOfWeek?.map { it.value }?.joinToString(separator = SEPARATOR)
@TypeConverter
@JvmStatic
fun stringToDaysOfWeek(daysOfWeek: String?): MutableList<DayOfWeek>? =
daysOfWeek?.split(SEPARATOR)?.map { DayOfWeek.of(it.toInt()) }?.toMutableList()
}
}
This is not perfect solution, but hope you can investigate more with that.
Also you need to change @PrimaryKey
to be not nullable
The full signature of List
in Kotlin is List<out E>
(List<? extend E>
in Java), it doesn't make any sense to convert such generic type. In other words, Room doesn't know if the input is a DayOfWeek
or its subclass.
As for ArrayList
and MutableList
, their full signature is ArrayList<E>
and MutableList<E>
correspondingly, the input type is fixed and hence Room knows how to convert it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With