Android room persistent library - TypeConverter error of error: Cannot figure out how to save field to database
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.
Android Room - error: Cannot figure out how to save this field into database
Date
is exactly the example given in https://developer.android.com/training/data-storage/room/referencing-data.
For example, if we want to persist instances of Date, we can write the following TypeConverter to store the equivalent Unix timestamp in the database:
public class Converters {
@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();
}
}
The preceding example defines 2 functions, one that converts a Date object to a Long object and another that performs the inverse conversion, from Long to Date. Since Room already knows how to persist Long objects, it can use this converter to persist values of type Date.
Next, you add the @TypeConverters annotation to the AppDatabase class so that Room can use the converter that you've defined for each entity and DAO in that AppDatabase:
AppDatabase.java
@Database(entities = {User.class}, version = 1)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
A side note: java.util.Date
is considered to be badly designed (and java.util.Calendar
is much worse). If you have any non-trivial date-time logic and can get away with API level 26 (Java 8 on desktop), it's generally better to use java.time
package. And if you can't, see https://github.com/JakeWharton/ThreeTenABP for a backport.
Kotlin Room Error Cannot figure out how to save this field into database With TypeConverters
I'm going to have to disagree with the answer from @DivijGupta, you can put the @TypeConverters
annotation on entity fields and it will limit the scope of the converter to that particular field as I am sure you intended. The documentation here actually lists the usage as:
If you put it on an Entity field, only that field will be able to use it.
The error is actually to do with how Kotlin translates the annotations into Java bytecode. If you have a look at what adding an annotation to a field actually does in the decompiled code, you can see that Kotlin places it on the constructor parameter, not the field itself. Therefore as Room doesn't see an annotation on the field it gives you the error.
To fix this you have to use an extra field
qualifier when annotating, in this instance:
@field:TypeConverters(FrequencyTypeConverter::class)
and you can read more about this in the Kotlin documentation on Annotation use-site targets.
Just as a side note, the answer from @DivijGupta would fix the error as the problem that I have outlined wouldn't exist, but it is just a workaround.
Room error - Cannot figure out how to save this field into database. You can consider adding a type converter for it.
You cant use entities inside other entities (e.g. Film in Reservation). You should either use "relationships between entities" or try "Embedded" annotation.
Reffer to this link for more info.
error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. in my app?
The typeConvertor seems to be a bit off. Instead of object let it be a class. Store in DB as JSON string and retrieve it ( GSON library optional).
class SourceTypeConverter {
@TypeConverter
fun fromSource(source: Source): String {
return JSONObject().apply {
put("id", source.id)
put("name", source.name)
}.toString()
}
@TypeConverter
fun toSource(source: String): Source {
val json = JSONObject(source)
return Source(json.get("id"), json.getString("name"))
}
}
Now register this TypeConvertor to the Database with annotation TypeConverter
.
@Database(entities = [Article::class], version = 1, exportSchema = false)
@TypeConverters(SourceTypeConverter::class)
abstract class SportNewsDatabase : RoomDatabase() {
/* your code here */
}
Cannot figure out how to save this field into database. I have written data class,dao and typeconverters, but still unable to detect error
I think your DataTypeConverter is wrong you can try change like this :
class DataTypeConverter{
var gson = Gson()
@TypeConverter
fun stringToUserList(data: String?): List<User?>? {
if (data == null) {
return Collections.emptyList()
}
val listType: Type =
object : TypeToken<List<User?>?>() {}.type
return gson.fromJson<List<User?>>(data, listType)
}
@TypeConverter
fun userDetailListToString(someObjects: List<User?>?): String? {
return gson.toJson(someObjects)
}
}
Don't forget to add @TypeConverters(DataTypeConverter::class)
to @Database
Related Topics
Preventing/Catching "Illegalargumentexception: Parameter Must Be a Descendant of This View" Error
Clear Text in Edittext When Entered
How to Send the Sms More Than 160 Character
Save State of Activity When Orientation Changes Android
Trying to Uninstall_Shortcut But Shortcut Won't Go Away
Font Size Too Large to Fit in Cache
Eclipse Installation Error: Install_Failed_Uid_Changed
"You Need to Use a Theme.Appcompat Theme (Or Descendant) with the Design Library" Error
Why Getapplicationcontext() in Constructor of Activity Throws Null Pointer Exception
How to Modify Ripple Color When Using Attr/Selectableitembackground as Background
Error Inflating Class Androidx.Constraintlayout.Constraintlayout After Migration to Androidx
Gridview with Different Cells Sizes, Pinterest Style
How to Create Always-Top Fullscreen Overlay Activity in Android
Why Is Android Webview Refusing User Input