Android Phone Permanent Library - TypeConverter Error Error: Unable to determine how to save field to database "

I was unable to create the type Converter in the room due to an error. I seem to be following the docs. I would like to convert the list to json string. let's look at my essence:

@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; } } 

country_lang is what I would like to convert to json string. Therefore, 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 that I put @TypeConverters ({Converters.class}), I keep getting the error. But officially, this is where I posted the annotation to register the Converter type:

 @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. 
+27
android android room
source share
8 answers

This is a common problem that I have seen since the announcement of Room. Room does not support the ability to store lists directly, as well as the ability to convert to / from lists. It supports POJO conversion and storage.

In this case, the solution is simple. Instead of saving the List<CountryLang> you want to save the CountryLangs (note the 's')

I made a quick example 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 the inverse of your previous object. This 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 rows and converts them to a comma-separated string, which will be stored in one column. When it extracts a string from SQLite db to convert back, it splits the list into commas and populates CountryLangs.

Forget updating the version of RoomDatabase after making these changes. You have the rest of the configuration correct. A happy hunt with the rest of your work perseverance in the room.

+27
source share

I had the same error: “Unable to figure out how to save this field in the database” when trying to add the “Date” field. I had to add a converter class to it and add the @TypeConverters annotation to the field.

Example:

WordEntity.java

 import android.arch.persistence.room.TypeConverters; @Entity public class WordEntity { @PrimaryKey(autoGenerate = true) public int id; private String name; @TypeConverters(DateConverter.class) private Date createDate; 

DateConverter.java:

 import android.arch.persistence.room.TypeConverter; import java.util.Date; public class DateConverter { @TypeConverter public static Date toDate(Long timestamp) { return timestamp == null ? null : new Date(timestamp); } @TypeConverter public static Long toTimestamp(Date date) { return date == null ? null : date.getTime(); } } 
+15
source share

@TypeConverter does not recognize the List class, so instead use an ArrayList , so you don’t need an extra wrapper for the list you want to keep.

+5
source share

I used the type converters described here (article on Medium.com) and it worked:

 @TypeConverter public static List<MyObject> storedStringToMyObjects(String data) { Gson gson = new Gson(); if (data == null) { return Collections.emptyList(); } Type listType = new TypeToken<List<MyObject>>() {}.getType(); return gson.fromJson(data, listType); } @TypeConverter public static String myObjectsToStoredString(List<MyObject> myObjects) { Gson gson = new Gson(); return gson.toJson(myObjects); } 
+5
source share

Kotlin example (not good, but simple, TODO: json):

 import android.arch.persistence.room.* @Entity(tableName = "doctor") data class DoctorEntity( @PrimaryKey @ColumnInfo(name = "id") val id: Long, @ColumnInfo(name = "contactName") val contactName: String?, @TypeConverters(CategoryConverter::class) @ColumnInfo(name = "categories") val categories: Categories?, @TypeConverters(CategoryConverter::class) @ColumnInfo(name = "languages") val languages: Categories? ) data class Categories( val categories: ArrayList<Long> = ArrayList() ) class CategoryConverter { @TypeConverter fun toCategories(value: String?): Categories { if (value == null || value.isEmpty()) { return Categories() } val list: List<String> = value.split(",") val longList = ArrayList<Long>() for (item in list) { if (!item.isEmpty()) { longList.add(item.toLong()) } } return Categories(longList) } @TypeConverter fun toString(categories: Categories?): String { var string = "" if (categories == null) { return string } categories.categories.forEach { string += "$it," } return string } } 
+2
source share

You should also create this TypeConverter which converts your List to String ,

 @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 for more information, you can also check my other answer .

+1
source share

There was the same problem. Change List to ArrayList . The list is an interface, and the room cannot save it.

0
source share

just annotating this object with @Embedded solved my problem. Like this

 @Embedded private List<CrewListBean> crewList; 
0
source share

All Articles