class MapConverters {
#TypeConverter
fun fromString(value: String): Map<Int, IntArray> {
val mapType = object : TypeToken<Map<Int, IntArray>>() {}.type
return Gson().fromJson(value, mapType)
}
#TypeConverter
fun fromMap(map: Map<Int, IntArray>): String {
val gson = Gson()
return gson.toJson(map)
}
}
#Entity
data class StartGame(
#PrimaryKey(autoGenerate = true) val gameId: Int?,
val gameName: String,
val scoreList: Map<Int, IntArray>
)
#Database(
entities = [StartGame::class, PersonList::class],
version = 1,
exportSchema = false
)
#TypeConverters(MapConverters::class){
...}
I got error
I want to put the Map type variable in Room.
I've tried many ways and tried to apply a typeConvertes.
But it didn't work well.
I'd like you to help me with this.
error: Not sure how to convert a Cursor to this method's return type (java.util.Map<java.lang.Integer, int[]>).
public abstract java.util.Map<java.lang.Integer, int[]> getGameScoreBoardById(int gameId);
#Dao
interface DataDao {
...
#Query("SELECT scoreList FROM StartGame WHERE gameId=:gameId")
#TypeConverters(MapConverters::class)
fun getGameScoreById(gameId: Int): Map<Int, IntArray>
D:\myapp\app_boardgame2\app\build\tmp\kapt3\stubs\debug\com\wonddak\boardmaster\room\DataDao.java:20: error: Not sure how to convert a Cursor to this method's return type (java.util.Map<java.lang.Integer, int[]>).
public abstract java.util.Map<java.lang.Integer, int[]> getGameScoreById(int gameId);
You need to specify which fields uses typeConverters in your model like -
#Entity
data class StartGame(
#PrimaryKey(autoGenerate = true) val gameId: Int?,
val gameName: String,
#TypeConverters(MapConverters::class)
val scoreList: Map<Int, IntArray>
)
Related
I am trying to make a type convertor for a model class in my app. The model class is given below.
Order
#Entity(tableName = "Orders")
data class Order(
#PrimaryKey
var customerId:String,
var companyId:String,
var orderBookerId:String,
#ColumnInfo(name = "items") var list:List<SelectedProductsModel>
)
SelectedProductsModel
data class SelectedProductsModel(
var quantity: Int,
var skuId: String,
var companyId: String,
var productName: String?,
var vendor_brand_name: String,
var purchasePrice: Int,
var image: String,
var position: Int
):Serializable
now as you can see that in the Order class there is a var list:List<SelectedProductsModel>. I want to write a type converter for this list but i keep getting an error
error: cannot find symbol
#androidx.room.TypeConverters(value = {SelectedProductModelConvertor.class})
following is my Room database class
#Database(entities = [VisitedPjpModel::class,Order::class], version = 1)
#TypeConverters(SelectedProductModelConvertor::class)
abstract class RoomDatabaseClass : RoomDatabase()
{
public abstract fun visitedDao(): VisitedPjpDao
public abstract fun orderDao():OrderDao
companion object
{
private var instance: RoomDatabaseClass? = null
fun getInstance(context: Context): RoomDatabaseClass?
{
if (instance == null)
{
synchronized(RoomDatabaseClass::class)
{
instance = Room.databaseBuilder(context, RoomDatabaseClass::class.java, "tarseel_database").allowMainThreadQueries().build()
}
}
return instance
}
}
}
i have tried different implementations of type convertors but iam getting the same error which is mentioned above. following are the implementations of type converotrs that i have tried
class SelectedProductModelConvertor
{
#TypeConverter
fun fromList(value : List<SelectedProductsModel>) = Json.encodeToString(value)
#TypeConverter
fun toList(value: String) = Json.decodeFromString<List<SelectedProductsModel>>(value)
}
class SelectedProductModelConvertor
{
#TypeConverter
fun listToJson(value: List<SelectedProductsModel>) = Gson().toJson(value)
#TypeConverter
fun jsonToList(value: String) = Gson().fromJson(value, Array<SelectedProductsModel>::class.java).toList()
}
class SelectedProductModelConvertor
{
#TypeConverter
fun fromListLangList(value: List<SelectedProductsModel>): String
{
val gson = Gson()
val type = object : TypeToken<List<SelectedProductsModel>>()
{}.type
return gson.toJson(value, type)
}
#TypeConverter
fun toSelectedProductsModelList(value: String): List<SelectedProductsModel>
{
val gson = Gson()
val type = object : TypeToken<List<SelectedProductsModel>>()
{}.type
return gson.fromJson(value, type)
}
}
I have tried all these type convertors but iam getting error. please help me
You cannot have a List/Array for a column.
What you can do, is have a class that holds the List/Array and have a Type Converter for that.
So you could have:-
data class SelectedProductsModelList(
val selectedProductsModelList: List<SelectedProductsModel>
)
Then have :-
#Entity(tableName = "Orders")
data class Order(
#PrimaryKey
var customerId:String,
var companyId:String,
var orderBookerId:String,
#ColumnInfo(name = "items") var list:SelectedProductsModelList //<<<<<<<<<<
)
and TypeConverters that convert from/to a SelectProductsModelList object e.g.
#TypeConverter
fun fromSelectedProductsModelList(selectedProductsModelList: SelectedProductsModelList): String {
return Gson().toJson(selectedProductsModelList)
}
#TypeConverter
fun toSelectedProductsModelList(json: String): SelectedProductsModelList {
return Gson().fromJson(json,SelectedProductsModelList::class.java)
}
Here is the code snippet in where Results data class contains list of objects:
#Entity(tableName = "objects_table")
data class Subscriber(
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = "object_id")
var id: Int,
#ColumnInfo(name = "object_name")
var name: Results?,
#ColumnInfo(name = "detected_time")
var confidence: Results?
)
I tried Type converter but simililar error:
#TypeConverter
fun restoreList(listOfString: String?): List<String?>? {
return Gson().fromJson<List<String?>>(listOfString, object : TypeToken<List<String?>?>() {}.type)
}
#TypeConverter
fun saveList(listOfString: List<String?>?): String? {
return Gson().toJson(listOfString)
}
The error is
error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
Thanks in advance!
the type converter needed is type converter for the "Results" class not the String list you did
Seems like you forgot to apply your TypeConverter class to your room database.
For example:
Database (note: you can have multiple TypeConverters)
#TypeConverters(
value = [
MyTypeConverters::class,
MyOtherTypeConverters::class
]
)
abstract class MyDatabase : RoomDatabase() {
...
}
TypeConverter
class MyTypeConverters {
#TypeConverter
fun restoreList(listOfString: String?): List<String?>? {
return Gson().fromJson<List<String?>>(listOfString, object : TypeToken<List<String?>?>() {}.type)
}
#TypeConverter
fun saveList(listOfString: List<String?>?): String? {
return Gson().toJson(listOfString)
}
}
Add #Embedded annotation to your reference type variable.
Like that:
#Entity(tableName = "objects_table")
data class Subscriber(
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = "object_id")
var id: Int,
#Embedded(prefix = "name_")
var name: Results?,
#Embedded(prefix = "confidence_")
var confidence: Results?
)
I'm doing weather app in Kotlin, and in Activity is method which firstly takes cache data from Room, and after one hour data is updated. But there is problem probably with saving of data in database. I checked API logs in Profiles and there is no null with Weather List, so API works fine.
I'm trying to save Weather list as an ArrayList, but the answer from logs is still null. I also tried Type Converter, but still nothing. Maybe someone will find the reason for my problem and the answer.
EDIT: I removed #Embedded(prefix = "weather_") above the ArrayList and it works.
CurrentWeather (stores Weather ArrayList):
#Entity(tableName = "current_weather")
data class CurrentWeather(
#Embedded(prefix = "weather_")
val weather: ArrayList<Weather>? = ArrayList(), //here is my problem
#SerializedName("base")
val base: String,
#Embedded(prefix = "clouds_")
val clouds: Clouds,
#SerializedName("cod")
val cod: Int,
#Embedded(prefix = "coord_")
val coord: Coord,
#SerializedName("dt")
val dt: Int,
#SerializedName("id")
val id: Int,
#Embedded(prefix = "main_")
val main: Main,
#SerializedName("name")
val name: String,
#Embedded(prefix = "sys_")
val sys: Sys,
#SerializedName("visibility")
val visibility: Int,
#Embedded(prefix = "wind_")
val wind: Wind
) {
#PrimaryKey(autoGenerate = false)
var idKey: Int = CURRENT_WEATHER_ID
}
Weather:
data class Weather(
#SerializedName("description")
val description: String,
#SerializedName("icon")
val icon: String,
#SerializedName("id")
val id: Int,
#SerializedName("main")
val main: String
)
Converter:
class Converters {
#TypeConverter
fun arrayListToJson(value: List<Weather>?): String {
return Gson().toJson(value)
}
#TypeConverter
fun jsonToArrayList(value: String): List<Weather> {
val objects = Gson().fromJson(value, Array<Weather>::class.java) as Array<Weather>
val list = objects.toList()
return list
}
Database:
#Database(entities = [CurrentWeather::class, Location::class], version = 15, exportSchema = false)
#TypeConverters(Converters::class) //converter initialization
abstract class WeatherDatabase : RoomDatabase() {
Here is the modified converter class. It might help you.
object class Converters {
val gson = Gson()
#TypeConverter
fun arrayListToJson(list: List<Weather>?): String? {
return if(list == null) null else gson.toJson(list)
}
#TypeConverter
fun jsonToArrayList(jsonData: String?): List<Weather>? {
return if (jsonData == null) null else gson.fromJson(jsonData, object : TypeToken<List<Weather>?>() {}.type)
}
}
I'm trying to save List<Object> into Room database.
I get following error:
error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
private java.util.List<xxx.models.OBJECTX> carList;
Room implementation:
#Entity(tableName = "nameOfTable")
class CachedObjectX(
#PrimaryKey
#ColumnInfo(name = "id") val id: Long,
#ColumnInfo(name = "list")
var carList: List<ObjectX>
)
#Dao
interface CachedObjectXDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(list: ArrayList<CachedObjectX>)
#Delete
fun delete(list: ArrayList<CachedObjectX>)
#Query("SELECT * FROM ...")
fun getAll(): ArrayList<CachedObjectX>
}
class CachedObjectXConverter {
companion object {
var gson = Gson()
#TypeConverter
#JvmStatic
fun toInsuredVehicle(json: String): List<ObjectX> {
val type = object : TypeToken<List<ObjectX>>() {}.type
return gson.fromJson(json, type)
}
#TypeConverter
#JvmStatic
fun toJson(torrent: List<ObjectX>): String {
val type = object: TypeToken<List<ObjectX>>() {}.type
return gson.toJson(torrent, type)
}
}
}
#Database(entities = [CachedObjectX::class], version = 1, exportSchema = false)
#TypeConverters(CachedObjectXConverter::class)
abstract class CachedObjectXDb : RoomDatabase() {
companion object {
private const val DB_NAME = "CachedObjectX.db"
val instance: CachedObjectXDb by lazy {
Room.databaseBuilder(
getContext(),
CCchedObjectXDb::class.java,
DB_NAME
).build()
}
}
abstract fun getDao(): CachedObjectXDao
}
Interesting, that I've added TypeConverter, but it still throws error. What is wrong with my implementation? Just started with Room, so there is high chance that something is wrong. Thanks in advance.
You have to make the pojo of ObjectX be an entity too
my DB is set up well, but now I am shifting from:
var note_items: MutableList<String>
to:
var note_items: MutableList<NoteItem>
and I get an error that note_items column is not recognized...
even when adding #columnInfo:
#Parcelize
#Entity(tableName = "note_table")
data class Note(var title: String
, #ColumnInfo(name = "note_items") var note_items: MutableList<NoteItem>
, #PrimaryKey(autoGenerate = true) var id: Long = 0
) : Parcelable {
}
#Parcelize
#Entity
data class NoteItem(#PrimaryKey /*#ColumnInfo(name = "note_items")*/ var text: String,
var description: String ): Parcelable
only if I add the #ColumnInfo to a var within NoteItem, does the app recognize and run but I wish to retrieve the ENTIRE object and not just a single var within it.
#Query("SELECT note_items FROM note_table WHERE id = :noteId")
fun getNoteItems(noteId: Long): LiveData<MutableList<NoteItem>>
adding my Converters class just in case:
class Converters {
companion object {
#TypeConverter
#JvmStatic
fun listToJson(value: MutableList<NoteItem>): String {
return Gson().toJson(value)
}
#TypeConverter
#JvmStatic
fun jsonToList(value: String?): MutableList<NoteItem> {
val gson = Gson()
val type= object : TypeToken<MutableList<NoteItem>?>() {}.type
return gson.fromJson(value, type)
}
}
}
Don't forget to add the TypeConverters to your database
#TypeConverters(Converters::class)
abstract class AppDatabse : RoomDatabase() {
//
}
And also in your note_items field of entity if needed
#TypeConverters(Converters::class)
#ColumnInfo(name = "note_items")
var note_items: MutableList<NoteItem>
Also update your Converters like below to keep it simple:
object Converters {
#TypeConverter
#JvmStatic
fun listToJson(value: MutableList<NoteItem>): String {
return Gson().toJson(value)
}
#TypeConverter
#JvmStatic
fun jsonToList(value: String?): MutableList<NoteItem> {
val gson = Gson()
val type= object : TypeToken<MutableList<NoteItem>?>() {}.type
return gson.fromJson(value, type)
}
}