Android room persistent library - how to insert class that has a List object field

You can easly insert the class with list object field using TypeConverter and GSON,

public class DataConverter {

    @TypeConverter
    public String fromCountryLangList(List<CountryLang> countryLang) {
        if (countryLang == null) {
            return (null);
        }
        Gson gson = new Gson();
        Type type = new TypeToken<List<CountryLang>>() {}.getType();
        String json = gson.toJson(countryLang, type);
        return json;
    }

    @TypeConverter
    public List<CountryLang> toCountryLangList(String countryLangString) {
        if (countryLangString == null) {
            return (null);
        }
        Gson gson = new Gson();
        Type type = new TypeToken<List<CountryLang>>() {}.getType();
        List<CountryLang> countryLangList = gson.fromJson(countryLangString, type);
        return countryLangList;
    }
 }

And add @TypeConverters Annotation before your list object field,

@Entity(tableName = TABLE_NAME)
public class CountryModel {

//....

@TypeConverters(DataConverter.class)
    public List<CountryLang> getCountryLang() {
        return countryLang;
    }
//....
} 

For more information about TypeConverters in Room check our blog here and the official docs.


Here is the Aman Gupta's converter in Kotlin for lazy Googler's who enjoy copy pasting:

class DataConverter {

    @TypeConverter
    fun fromCountryLangList(value: List<CountryLang>): String {
        val gson = Gson()
        val type = object : TypeToken<List<CountryLang>>() {}.type
        return gson.toJson(value, type)
    }

    @TypeConverter
    fun toCountryLangList(value: String): List<CountryLang> {
        val gson = Gson()
        val type = object : TypeToken<List<CountryLang>>() {}.type
        return gson.fromJson(value, type)
    }
}

As Omkar said, you cannot. Here, I describe why you should always use @Ignore annotation according to the documentation: https://developer.android.com/training/data-storage/room/referencing-data.html#understand-no-object-references

You will treat the Country object in a table to retrieve the data of its competence only; The Languages objects will go to another table but you can keep the same Dao:

  • Countries and Languages objects are independent, just define the primaryKey with more fields in Language entity (countryId, languageId). You can save them in series in the Repository class when the active thread is the Worker thread: two requests of inserts to the Dao.
  • To load the Countries object you have the countryId.
  • To load the related Languages objects you already have the countryId, but you will need to wait that country is loaded first, before to load the languages, so that you can set them in the parent object and return the parent object only.
  • You can probably do this in series in the Repository class when you load the country, so you will load synchronously country and then languages, as you would do at the Server side! (without ORM libraries).