Home > database >  Adding Date TypeConverter causes Room to fail storing API results
Adding Date TypeConverter causes Room to fail storing API results

Time:10-04

I have searched for quite a while and am at a loss. My app makes some fairly routine API calls and stores the results in a Room DB, this all works perfectly until I try and utilize a TypeConverter for a date field by changing the data type of a parameter in one of my classes/tables. The problem is I'm not getting any error, it's simply not storing any data in the Room database the moment I switch the type. I swear I've implemented this correctly based on everything I've read and seen, I tested the converter function with mock data as my API returns and that is working. I can't seem to figure out what Room is doing and where this is breaking down.

Here is the relevant portion of my data class, if dateAdded were declared as String? everything works fine:

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName
import java.util.*

@Entity
data class Cocktail (
    ...
    @ColumnInfo(name = "date_added")
    @SerializedName("dateadded")
    val dateAdded: Date?
)

API returns:

[
   {
      ...
      "dateadded": "2020-04-03 13:15:56"
   }
]

Database:

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.goodcall.goodcall.data.models.*

@Database(
    entities = arrayOf(
        Cocktail::class,
        CocktailRecipe::class,
        CocktailIngredient::class,
        IngredientType::class,
        Lists::class,
        ListsDrinksItems::class
    ),
    version = 1,
    exportSchema = false
)
@TypeConverters(Converters::class)
abstract class GoodCallDatabase : RoomDatabase() {
    abstract fun goodCallDao(): GoodCallDao

    companion object {
        @Volatile private var instance: GoodCallDatabase? = null
        private val LOCK = Any()

        operator fun invoke(context: Context) = instance ?: synchronized(LOCK) {
            instance ?: buildDatabase(context).also {
                instance = it
            }
        }
        private fun buildDatabase(context: Context) = Room.databaseBuilder(
            context.applicationContext,
            GoodCallDatabase::class.java,
            "goodcalldatabase.db"
        )
            .build()
    }
}

Converter class:

import androidx.room.TypeConverter
import java.text.SimpleDateFormat
import java.util.*

class Converters {
    @TypeConverter
    fun fromTimestampStr(timeStamp: String?): Date? {
        if(timeStamp == null){
            return null
        } else {
            val date = SimpleDateFormat("YYYY-MM-dd HH:mm:ss").parse(timeStamp)
            return date
        }
    }
    @TypeConverter
    fun toTimestampStr(date: Date?): String? {
        if(date == null){
            return null
        } else {
            val format = SimpleDateFormat("YYYY-MM-dd HH:mm:ss")
            return format.format(date)
        }
    }
}

Appreciate any and all help here, I'm pretty much a novice with Android so hoping this is a simple fix.

CodePudding user response:

I think your problem isn't with the Room, Did you add DateDeserializer to your GsonBuilder?
Kotlin

class DateDeserializer : JsonDeserializer<Date> {

@Throws(JsonParseException::class)
override fun deserialize(
    json: JsonElement,
    typeOfT: Type,
    context: JsonDeserializationContext
): Date {
}}

Java

public class DateDeserializer implements JsonDeserializer<Date> {

public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
}}

if had this is implemented, I suggest changing your file signature from class to object.

  • Related