How to save nested List<String> in RoomDB on Android

12,382

I had the same issue, which I solved with @TypedConverter. I am saving the list as JSONArray.toString in the db.

@TypeConverter
public static List<String> restoreList(String listOfString) {
    return new Gson().fromJson(listOfString, new TypeToken<List<String>>() {}.getType());
}

@TypeConverter
public static String saveList(List<String> listOfString) {
    return new Gson().toJson(listOfString);
}

This way every List<String> will be serialized as a JSONArray in your db.

To your db class, the one that extends RoomDatabase, you will have to declare which class to use for this conversion with @TypeConverters(Converters.class). E.g.

@Database(version = 1, entities = {Entity.class})
@TypeConverters(Converters.class)
public abstract class MoviesDatabase extends RoomDatabase {
Share:
12,382
murt
Author by

murt

Updated on June 11, 2022

Comments

  • murt
    murt about 2 years

    Hey google have an example on using @Relation

    @Entity
     public class Pet {
         int userId;
         String name;
         // other fields
     }
     public class UserNameAndAllPets {
       public int id;
       public String name;
       @Relation(parentColumn = "id", entityColumn = "userId")
       public List<Pet> pets;
     }
    

    Is it possible to save list of String without creating extra class for it. I want to avoid incosistence between my JsonProperty and a room Entity

    W would like to have soemthing like that

     public class UserNameAndAllPets {
       @JsonProperty("id")
       public int id;
       @JsonProperty("name")
       public String name;
       @Relation(parentColumn = "id")
       @JsonProperty("pets")
       public List<String> pets;
     }
    

    Because I receive following Json:

    { 
     "id" : "1",
    "name" : "someName",
    "pets": ["cat", "dog", "camel"]
    }
    

    Any one know the solution?

    EDIT:

    now my example code looks like But I've got Error: Error:Type of the parameter must be a class annotated with @Entity or a collection/array of it.

    @JsonIgnoreProperties(ignoreUnknown=true)
    @Entity(tableName = TABLE_NAME)
    public class Item {
        @Ignore public static final String TABLE_NAME = "itemTable";
    
        @PrimaryKey(autoGenerate = true)
        Long id;
        @JsonProperty("supplierName")
        String supplierName;
        @JsonProperty("eventDescription")
        String eventDescription;
        @JsonProperty("eventDate")
        @TypeConverters(StringListToGsonConverter.class)
        Date date;
        @JsonProperty("carServiceType")
        @TypeConverters(StringListToGsonConverter.class)
        List<String> types;
    
        public ServiceHistoryItem(Long id, String supplierName, String eventDescription, Date date, List<String> types) {
            this.id = id;
            this.supplierName = supplierName;
            this.eventDescription = eventDescription;
            this.date = date;
            this.types = types;
        }
    
        public static class StringListToGsonConverter{
            @TypeConverter
            public static List<String> restoreList(String listOfString){
                return new Gson().fromJson(listOfString, new TypeToken<List<String>>() {}.getType());
            }
    
            @TypeConverter
            public static String saveListOfString(List<String> listOfString){
                return new Gson().toJson(listOfString);
            }
    
            @TypeConverter
            public static Date fromTimestamp(Long value) {
                return value == null ? null : new Date(value);
            }
    
            @TypeConverter
            public static Long dateToTimestamp(Date date) {
                return date == null ? null : date.getTime();
            }
        }
    }
    

    EDIT2

    New Issue arise when saving items Dao cannot insert List of My Entities, no reason Why... though Error:Type of the parameter must be a class annotated with @Entity or a collection/array of it.

    @Dao
    interface ItemDao {
        @Query("SELECT * FROM " + Item.TABLE_NAME)
        fun getAll(): LiveData<List<Item>>
    
        @Query("DELETE FROM " + Item.TABLE_NAME)
        fun deleteAllServiceHistory()
    
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        fun insertNewItem(item: Item)
    
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        fun insertNewItems(itemList: List<Item>) // <--- Error
    
    }
    

    SOLUTION for Dao

    if you are using Kotlin you should use ArrayList

    @Insert(onConflict = OnConflictStrategy.REPLACE)
            fun insertNewItems(itemList: ArrayList<Item>)