Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Room Database: How to handle Arraylist in an Entity?

People also ask

How do you store objects in a room?

Convert Object/ List<Object> to String and then, Store it. You can store the objects in Room Library as String. For that, you can serialize the object and store it as String in the Room Database.

What is the difference between SQLite and room database in Android?

Room vs SQLiteRoom provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. In the case of SQLite, There is no compile-time verification of raw SQLite queries. But in Room, there is SQL validation at compile time.


Type Converter are made specifically for that. In your case, you can use code snippet given below to store data in DB.

public class Converters {
    @TypeConverter
    public static ArrayList<String> fromString(String value) {
        Type listType = new TypeToken<ArrayList<String>>() {}.getType();
        return new Gson().fromJson(value, listType);
    }

    @TypeConverter
    public static String fromArrayList(ArrayList<String> list) {
        Gson gson = new Gson();
        String json = gson.toJson(list);
        return json;
    }
}

And mention this class in your Room DB like this

@Database (entities = {MainActivityData.class},version = 1)
@TypeConverters({Converters.class})

More info here


Option #1: Have MyListItems be an @Entity, as MainActivityData is. MyListItems would set up a @ForeignKey back to MainActivityData. In this case, though, MainActivityData cannot have private ArrayList<MyListItems> myListItems, as in Room, entities do not refer to other entities. A view model or similar POJO construct could have a MainActivityData and its associated ArrayList<MyListItems>, though.

Option #2: Set up a pair of @TypeConverter methods to convert ArrayList<MyListItems> to and from some basic type (e.g., a String, such as by using JSON as a storage format). Now, MainActivityData can have its ArrayList<MyListItems> directly. However, there will be no separate table for MyListItems, and so you cannot query on MyListItems very well.


Kotlin version for type converter:

 class Converters {

    @TypeConverter
    fun listToJson(value: List<JobWorkHistory>?) = Gson().toJson(value)

    @TypeConverter
    fun jsonToList(value: String) = Gson().fromJson(value, Array<JobWorkHistory>::class.java).toList()
}

I Used JobWorkHistory object for my purpose, use the object of your own

@Database(entities = arrayOf(JobDetailFile::class, JobResponse::class), version = 1)
@TypeConverters(Converters::class)
abstract class MyRoomDataBase : RoomDatabase() {
     abstract fun attachmentsDao(): AttachmentsDao
}

Better version of List<String> converter

class StringListConverter {
    @TypeConverter
    fun fromString(stringListString: String): List<String> {
        return stringListString.split(",").map { it }
    }

    @TypeConverter
    fun toString(stringList: List<String>): String {
        return stringList.joinToString(separator = ",")
    }
}

Native Kotlin version using Kotlin's serialization component – kotlinx.serialization.

  1. Add the Kotlin serialization Gradle plugin and dependency to your build.gradle:
apply plugin: 'kotlinx-serialization'

dependencies {
   ...
   implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1"
}
  1. Add the Type converters to your Converter class;
class Converters {
   @TypeConverter
   fun fromList(value : List<String>) = Json.encodeToString(value)

   @TypeConverter
   fun toList(value: String) = Json.decodeFromString<List<String>>(value)
}
  1. Add your Converter class to your database class:
@TypeConverters(Converters::class)
abstract class YourDatabase: RoomDatabase() {...}

And you're done!

Extra resources:

  • Type Converters
  • Kotlin Serialization