La bibliothèque Room ne reconnaît pas un TypeConverter
que j'ai créé pour un List
d'énumérations. Cependant, lorsque je change cela en ArrayList
d'énumérations, cela fonctionne très bien. Tout le monde sait pourquoi et que puis-je faire pour que cela fonctionne avec List
? (Utiliser List dans Kotlin est plus facile et je ne veux vraiment pas convertir en avant et en arrière en ArrayList
juste à cause de cela).
Voici mon code:
Mon modele:
@Entity
data class Example(@PrimaryKey val id: String?,
val name: String,
var days: List<DayOfWeek>?)
DayOfWeek
est une énumération:
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]
}
}
}
Mon 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()) }
}
}
Et je l'ai mis dans ma classe DB comme ceci:
@Database(entities = arrayOf(Example::class), version = 1)
@TypeConverters(DayOfWeekConverter::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun exampleDao(): ExampleDao
}
Mon DAO ressemble à ceci:
@Dao
interface ExampleDao {
@Query("SELECT * FROM example")
fun getAll(): LiveData<List<Example>>
@Insert(onConflict = REPLACE)
fun save(examples: List<Example>)
}
L'erreur que j'obtiens avec ce code est:
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;
Comme je l'ai dit ci-dessus, si je change la propriété days
en ArrayList<DayOfWeek>
(et apportez les modifications à ArrayList
dans DayOfWeekConverter
) alors tout fonctionne correctement. Si quelqu'un peut m'aider à comprendre cela et me dire comment je peux utiliser List
ici, ce serait d'une grande aide, cela me rend fou: /.
Pour une raison quelconque, Room n'aime pas Kotlin List
, mais quand j'ai remplacé List
par MutableList
, cela a commencé à fonctionner:
@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()
}
}
Ce n'est pas une solution parfaite, mais j'espère que vous pourrez en savoir plus avec cela.
Vous devez également modifier @PrimaryKey
pour ne pas être annulable
La signature complète de List
dans Kotlin est List<out E>
(List<? extend E>
en Java), cela n'a aucun sens de convertir ce type générique. En d'autres termes, Room ne sait pas si l'entrée est un DayOfWeek
ou sa sous-classe.
Quant à ArrayList
et MutableList
, leur signature complète est ArrayList<E>
et MutableList<E>
en conséquence, le type d'entrée est fixe et donc Room sait comment le convertir.