[ksp] java.lang.IllegalArgumentException: List has more than one element.

Skele·2024년 6월 22일

DevLog

목록 보기
4/4

Error code

[ksp] java.lang.IllegalArgumentException: List has more than one element.
	at kotlin.collections.CollectionsKt___CollectionsKt.single(_Collections.kt:610)
	at androidx.room.ext.Xelement_extKt.getValueClassUnderlyingProperty(xelement_ext.kt:35)
	at androidx.room.solver.TypeAdapterStore.createDefaultTypeAdapter(TypeAdapterStore.kt:383)
	at androidx.room.solver.TypeAdapterStore.findColumnTypeAdapter(TypeAdapterStore.kt:368)
...

Version used in project

kotlin = "1.9.0"
ksp = "1.9.0-1.0.13"
room = "2.6.1"

Presumed problem - Type compatibility for Room

The error did not show where the problem was caused specifically, but with some research, it all pointed toward the Room.
Reference : Same error on ksp issue
It seemed storing data of types that are not supported by the Room causes this error.

As Room uses SQLite for internal storage, only the types that supported can be stored in the Room database.
Types that are not supported can be converted via TypeConverter provided in Room API.

@Entity(tableName = "task")
data class Task(
    @PrimaryKey(autoGenerate = true) val id : Long,
    var description : String,
    var workTime : Duration,
    var breakTime : Duration,
    var longBreakTime : Duration,
    var dailyGoal : Int,
    var priority : Int,
    var color : Color,
)

I tried to use two converters for kotlin.time.Duration and androidx.compose.ui.graphics.Color.

class DurationConverter {
    @TypeConverter
    fun fromMilliseconds(value: Long?) : Duration? {
        return value?.milliseconds
    }
    @TypeConverter
    fun fromDuration(time: Duration?) : Long? {
        return time?.inWholeMilliseconds
    }
}
class ColorConverter {
    @TypeConverter
    fun fromInt(value: Int?) : Color? {
        return value?.let { Color(it) }
    }
    @TypeConverter
    fun fromColor(color: Color?) : Int? {
        return color?.toArgb()
    }
}

Even though, with these two converters annotated to Database, compiler threw an error and could not build the project.
With some reason, compiler would not convert data types accordingly.
Because this error is caused by internal process inside ksp and room, finding exact reason would have been time-consuming.

Solution

By sticking to the principle, the problem can be solved quite easily.
This time, solved the problem by only using primitive types that are supported in the Room, and provied converted member fields for easy-use.

@Entity(tableName = "task")
data class Task(
    @PrimaryKey(autoGenerate = true) val id : Long,
    var description : String,
    var workTimeInMillisec : Long,
    var breakTimeInMillisec : Long,
    var longBreakTimeInMillisec : Long,
    var dailyGoal : Int,
    var priority : Int,
    var colorNum : Int,
){
	@Ignore
    val workTime = workTimeInMillisec.milliseconds
    @Ignore
    val breakTime = breakTimeInMillisec.milliseconds
    @Ignore
    val longBreakTime = longBreakTimeInMillisec.milliseconds
    @Ignore
    val color = Color(colorNum)
}
profile
Tireless And Restless Debugging In Source : TARDIS

0개의 댓글