Home > database >  Problem in TypeConverters In Room Database
Problem in TypeConverters In Room Database

Time:11-10

I am trying to use type converters in Android (Kotlin) so i am using the type converters class but i am getting confused like inside of the clouds i am having a single variable so i have returned it but

@Entity(tableName = "WeatherDb")
data class WeatherDTO(
    val base: String,
    val clouds: Clouds,
    val cod: Int,
    val coord: Coord,
    val dt: Int,
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val main: Main,
    val name: String,
    val sys: Sys,
    val timezone: Int,
    val visibility: Int,
    val weather: List<Weather>,
    val wind: Wind
)

class TypeConverters {
    @TypeConverter
    fun fromCloudsToDouble(clouds: Clouds): Int {
        return clouds.all
    }

    fun fromCoordToDouble(coord: Coord): Double {

    }
}

In coord class here are multiple with different datatypes how to covert this?

data class Main(
    val feels_like: Double,
    val grnd_level: Int,
    val humidity: Int,
    val pressure: Int,
    val sea_level: Int,
    val temp: Double,
    val temp_max: Double,
    val temp_min: Double
)

CodePudding user response:

Here is my converter in the Kotlin:

class Converters {

    @TypeConverter
    fun valueFromDomainToStorage(value: Value): String {
        return value.convertToJson()
    }

    @TypeConverter
    fun valueFromStorageToDomain(str: String): Value {
        // we can not create an empty instance of value as TypeDecoder.java should call non-empty constructor
        return Value(
            "just a stub",
            BigInteger.valueOf(0),
            BigInteger.valueOf(0),
            false,
            BigInteger.valueOf(0)
        )
            .fromJson(str)
    }
}

where .convertToJson() and .fromJson(str) implemented as extensions within Value class:

fun Value.convertToJson(): String {
    val result = JSONObject()
    result.put(ValueConst.OFFER_FIELD, offer)
    result.put(ValueConst.AVAILABLE_SINCE, availableSince.toLong())
    result.put(ValueConst.AVAILABLE_END, availabilityEnd.toLong())
    result.put(ValueConst.IS_CONSUMED, isConsumed)
    result.put(ValueConst.LOCKED_UNTIL, lockedUntil)
    return result.toString()
}

fun Value.fromJson(json: String): Value {
    val subj = JSONObject(json)
    return Value(
        subj.optString(ValueConst.OFFER_FIELD),
        BigInteger.valueOf(subj.optLong(ValueConst.AVAILABLE_SINCE)),
        BigInteger.valueOf(subj.optLong(ValueConst.AVAILABLE_END)),
        subj.optBoolean(ValueConst.IS_CONSUMED),
        BigInteger.valueOf(subj.optLong(ValueConst.LOCKED_UNTIL))
    )
}

You should implement Converter class for each non-native class type. Do not forget to register your converters on database:

@Database(entities = [ChainTransaction::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class AppDatabase: RoomDatabase() {

When you have compile the code and later introduce new changes, you have to increase version parameter too to make changes to take effect:

@Database(entities = [ChainTransaction::class], version = 2, exportSchema = false)
@TypeConverters(Converters::class)
abstract class AppDatabase: RoomDatabase() {

Here is official documentation and even training on this topic: enter image description here

  • The fields converted to a JSON string have been highlighted.
  • Obviously the data will very likely not exactly be as you would expect due to the made up classes.
  • Related