Himanshu Sehgal
Himanshu Sehgal

Reputation: 97

How to Save the HashMap in Room database without using JSON & GSON?

I am trying to store Address in HashMap but the compiler gives the error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. private java.util.HashMap address;

 error: 
    Cannot figure out how to save this field into database. You can consider adding a type converter for it. private java.util.HashMap<java.lang.String, java.lang.String> address;

I am using the MapTypeConverter but it doesn't work

object MapTypeConverter {

    @TypeConverter
    @JvmStatic
    fun stringToMap(value: JsonElement): Map<String, String> {
        return Gson().fromJson(value,  object : TypeToken<Map<String, String>>() {}.type)
    }

    @TypeConverter
    @JvmStatic
    fun mapToString(value: Map<String, String>?): String {
        return if(value == null) "" else Gson().toJson(value)
    }
}   

Room Entity

@Entity
data class User(
    var ownerName: String? = null,
    var shopNumber: String? = null,
    var deviceToken: String? = null,
    var altNumber: String? = null,
    var address: Map<String, String>? = null
) {
    @PrimaryKey(autoGenerate = false)
    var uId: String = "NA"
}

App DataBase

@Database(
    entities = [User::class,ProductDetails::class,CategoryDetails::class],
    version = 1
)
@TypeConverters(ConverterListToString::class,MapTypeConverter::class)
abstract class AppDatabase : RoomDatabase(){

    abstract fun getUserDao(): UserDao
    abstract fun getProductDao(): ProductDao
    abstract fun getCategoryDao(): CategoryDao

    companion object{

        @Volatile
        private var instance: AppDatabase? = null
        private val LOCK = Any()

        operator fun invoke(context: Context) = instance ?: synchronized(LOCK){
            instance ?: buildAppDataBase(context).also {
                instance = it
            }
        }

        private fun buildAppDataBase(context: Context) =
            Room.databaseBuilder(
                context.applicationContext,
                AppDatabase::class.java,
                 "TradersDatabase.db"
            ).build()
    }
}

Upvotes: 3

Views: 3569

Answers (2)

Md. Asaduzzaman
Md. Asaduzzaman

Reputation: 15423

Use String instead of JsonElement

object MapTypeConverter {

    @TypeConverter
    @JvmStatic
    fun stringToMap(value: String): Map<String, String> {
        return Gson().fromJson(value,  object : TypeToken<Map<String, String>>() {}.type)
    }

    @TypeConverter
    @JvmStatic
    fun mapToString(value: Map<String, String>?): String {
        return if(value == null) "" else Gson().toJson(value)
    }
}   

And your Entity should be like this

@Entity
data class User(
    var ownerName: String? = null,
    var shopNumber: String? = null,
    var deviceToken: String? = null,
    var altNumber: String? = null,

    @TypeConverters(MapTypeConverter::class)
    var address: Map<String, String>? = null
) {
    @PrimaryKey(autoGenerate = false)
    var uId: String = "NA"
}

Upvotes: 3

Abdul Kawee
Abdul Kawee

Reputation: 2727

You need to add converted to your entity

@Entity
data class User(
    var ownerName: String? = null,
    var shopNumber: String? = null,
    var deviceToken: String? = null,
    var altNumber: String? = null,
    @TypeConverters(MapTypeConverter::class)
    var address: Map<String, String>? = null
) {
    @PrimaryKey(autoGenerate = false)
    var uId: String = "NA"
}

You need to change JsonElement to String in stringToMap function

Hope this helps you.

Upvotes: 0

Related Questions