Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android room persistent library - TypeConverter error of error: Cannot figure out how to save field to database"

Im not able to create a typeConverter in room due to an error. I seem to be following everything per the docs. I would like to convert a list to a json string. lets take a look at my entity:

      @Entity(tableName = TABLE_NAME) public class CountryModel {      public static final String TABLE_NAME = "Countries";      @PrimaryKey     private int idCountry; /* I WANT TO CONVERT THIS LIST TO A JSON STRING */     private List<CountryLang> countryLang = null;      public int getIdCountry() {         return idCountry;     }      public void setIdCountry(int idCountry) {         this.idCountry = idCountry;     }      public String getIsoCode() {         return isoCode;     }      public void setIsoCode(String isoCode) {         this.isoCode = isoCode;     }      public List<CountryLang> getCountryLang() {         return countryLang;     }      public void setCountryLang(List<CountryLang> countryLang) {         this.countryLang = countryLang;     }  } 

The country_lang is what i would like to convert to a string json. So i created the following converter: Converters.java:

public class Converters {  @TypeConverter public static String countryLangToJson(List<CountryLang> list) {      if(list == null)         return null;          CountryLang lang = list.get(0);      return list.isEmpty() ? null : new Gson().toJson(lang); }} 

then the problem is anywhere i put the @TypeConverters({Converters.class}) i keep getting an error. But officially this is where i have placed the annotation to get the typeConverter registered:

@Database(entities = {CountryModel.class}, version = 1 ,exportSchema = false) @TypeConverters({Converters.class}) public abstract class MYDatabase extends RoomDatabase {     public abstract CountriesDao countriesDao(); } 

The error i get is:

Error:(58, 31) error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. 
like image 865
j2emanue Avatar asked Jun 16 '17 06:06

j2emanue


1 Answers

This is a common problem I've seen since Room was announced. Room does not support the ability to store Lists directly, nor the ability to convert to/from Lists. It supports converting and storing POJO's.

In this case the solution is simple. Instead of storing a List<CountryLang> you want to store CountryLangs (note the 's')

I've done a quick example of a solution here :

public class CountryLangs {     private List<String> countryLangs;      public CountryLangs(List<String> countryLangs) {         this.countryLangs = countryLangs;     }      public List<String> getCountryLangs() {         return countryLangs;     }      public void setCountryLangs(List<String> countryLangs) {         this.countryLangs = countryLangs;     } } 

This POJO is an inversion of your previous object. It is an object that stores a list of languages. Instead of a list of objects that store your language.

public class LanguageConverter {     @TypeConverter     public CountryLangs storedStringToLanguages(String value) {         List<String> langs = Arrays.asList(value.split("\\s*,\\s*"));         return new CountryLangs(langs);     }      @TypeConverter     public String languagesToStoredString(CountryLangs cl) {         String value = "";          for (String lang :cl.getCountryLangs())             value += lang + ",";          return value;     } } 

This converter takes a list of strings and converts them into a comma seperated string to be stored in a single column. When it fetches the string from the SQLite db to convert back, it splits the list on commas, and populates the CountryLangs.

Insure to update your RoomDatabase version after making these changes.You have the rest of the configuration correct. Happy hunting with the rest of your Room persistence work.

like image 191
Jack Dalton Avatar answered Sep 24 '22 01:09

Jack Dalton