web-dev-qa-db-ja.com

Android Roomエラー:TypeConverterが列挙型リストで認識されません

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>に変更した場合(およびArrayListDayOfWeekConverterを変更した場合)、すべて正常に機能します。誰かがこれを理解して私がListをどのように使用できるかを私に教えてくれるなら、それは大きな助けになるでしょう、それは私を夢中にさせています:/。

13
Franco

何らかの理由で、RoomはKotlin Listが好きではありませんが、ListMutableListに置き換えたところ、機能し始めました。

@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にできません

13
Tomek Polański

KotlinでのListの完全な署名はList<out E>List<? extend E>(Javaでは)、そのようなジェネリック型を変換しても意味がありません。つまり、Roomは入力がDayOfWeekかそのサブクラスかを認識していません。

ArrayListMutableListの完全な署名はArrayList<E>およびMutableList<E>対応して、入力タイプは固定されているため、Roomはそれを変換する方法を認識しています。

2
jaychang0917