Search code examples
androidkotlinenumsandroid-roomconverters

How to save enum field in the database room?


I must write the value from the enum enumeration to the database. An error occurs during compilation. What am I doing wrong?

Cannot figure out how to save this field into database. You can consider adding a type converter for it.

@ColumnInfo(name = "state_of_health")
@TypeConverters(HealthConverter::class)
var health: Health

enum class Health(val value: Int){
    NONE(-1),
    VERY_BAD(0),
    ...
}

class HealthConverter{

    @TypeConverter
    fun fromHealth(value: Health): Int{
        return value.ordinal
    }

    @TypeConverter
    fun toHealth(value: Int): Health{
        return when(value){
            -1 -> Health.NONE
            0 -> Health.VERY_BAD
            ...
            else -> Health.EXCELLENT
        }
    }

}

Solution

  • You can make a convert to each enum, like this:

    class Converters {
    
         @TypeConverter
         fun toHealth(value: String) = enumValueOf<Health>(value)
    
         @TypeConverter
         fun fromHealth(value: Health) = value.name
    }
    

    Or if you prefer store it as SQL integer, you can use ordinal too:

    class Converters {
    
        @TypeConverter
        fun toHealth(value: Int) = enumValues<Health>()[value]
    
        @TypeConverter
        fun fromHealth(value: Health) = value.ordinal
    }
    

    Unfortunatally, there is no way to use generics Enum<T> to accomplish this since unbound generics will raise an error Cannot use unbound generics in Type Converters.

    Android Room team could seriously add an annotation and a generator for Enums to their kapt compiler.

    Finally, annotate a database class, entity class, dao class, dao method, dao method parameter or entity field class with this:

    @TypeConverters(Converters::class)