Roomライブラリは、TypeConverter
列挙型用に作成したList
を認識しません。ただし、これを列挙型のArrayList
に変更すると、正常に動作します。誰もが何らかの考えを持っていますが、これをList
で機能させるにはどうすればよいですか? (KotlinでListを使用する方が簡単で、このために、変換してArrayList
に変換したくないのですが)。
これが私のコードです:
私のモデル:
@Entity
data class Example(@PrimaryKey val id: String?,
val name: String,
var days: List<DayOfWeek>?)
DayOfWeek
は列挙型です:
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]
}
}
}
私の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()) }
}
}
そして、私はそれを私のDBクラスに次のように設定しました:
@Database(entities = arrayOf(Example::class), version = 1)
@TypeConverters(DayOfWeekConverter::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun exampleDao(): ExampleDao
}
私のDAOは次のようになります。
@Dao
interface ExampleDao {
@Query("SELECT * FROM example")
fun getAll(): LiveData<List<Example>>
@Insert(onConflict = REPLACE)
fun save(examples: List<Example>)
}
このコードで発生するエラーは次のとおりです。
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;
上記で述べたように、days
プロパティをArrayList<DayOfWeek>
に変更した場合(およびArrayList
のDayOfWeekConverter
を変更した場合)、すべて正常に機能します。誰かがこれを理解して私がList
をどのように使用できるかを私に教えてくれるなら、それは大きな助けになるでしょう、それは私を夢中にさせています:/。
何らかの理由で、RoomはKotlin List
が好きではありませんが、List
をMutableList
に置き換えたところ、機能し始めました。
@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()
}
}
これは完全な解決策ではありませんが、それでさらに調査できることを願っています。
また、変更する必要があります@PrimaryKey
はnullにできません
KotlinでのList
の完全な署名はList<out E>
(List<? extend E>
(Javaでは)、そのようなジェネリック型を変換しても意味がありません。つまり、Roomは入力がDayOfWeek
かそのサブクラスかを認識していません。
ArrayList
とMutableList
の完全な署名はArrayList<E>
およびMutableList<E>
対応して、入力タイプは固定されているため、Roomはそれを変換する方法を認識しています。