Постоянная библиотека телефона Android - Ошибка ошибки TypeConverter: не удается определить, как сохранить поле в базу данных "
Мне не удалось создать типКонвертер в комнате из-за ошибки. Кажется, я следую за документами. Я хотел бы преобразовать список в строку json. давайте посмотрим на мою сущность:
@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 - это то, что я хотел бы преобразовать в строку json. Поэтому я создал следующий конвертер:
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);
}}
тогда проблема в том, что я помещаю @TypeConverters ({Converters.class}), я продолжаю получать ошибку. Но официально это то, где я разместил аннотацию, чтобы зарегистрировать типКонвертер:
@Database(entities = {CountryModel.class}, version = 1 ,exportSchema = false)
@TypeConverters({Converters.class})
public abstract class MYDatabase extends RoomDatabase {
public abstract CountriesDao countriesDao();
}
Ошибка, которую я получаю:
Error:(58, 31) error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
Ответы
Ответ 1
Это обычная проблема, которую я видел с момента объявления Room. Room не поддерживает возможность хранения списков напрямую, а также возможность конвертировать в/из списков. Он поддерживает преобразование и хранение POJO.
В этом случае решение прост. Вместо сохранения List<CountryLang>
вы хотите сохранить CountryLangs
(обратите внимание на 's')
Я сделал быстрый пример решения здесь:
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;
}
}
Это POJO - это инверсия вашего предыдущего объекта. Это объект, который хранит список языков. Вместо списка объектов, которые хранят ваш язык.
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;
}
}
Этот конвертер принимает список строк и преобразует их в разделенную запятыми строку, которая будет храниться в одном столбце. Когда он извлекает строку из SQLite db для преобразования обратно, он разбивает список на запятые и заполняет CountryLangs.
Забудьте обновить версию RoomDatabase после внесения этих изменений. У вас остальная конфигурация правильная. Счастливая охота с остальной частью вашей работы настойчивостью в номере.
Ответ 2
Имела ту же ошибку: "Невозможно выяснить, как сохранить это поле в базе данных" при попытке добавить поле "Дата". Пришлось добавить к нему класс конвертера и добавить в поле аннотацию @TypeConverters.
Пример:
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();
}
}
Ответ 3
@TypeConverter
не распознает класс List
, поэтому вместо этого следует использовать ArrayList
, поэтому вам не нужна дополнительная оболочка для списка, который вы хотите сохранить.
Ответ 4
Я использовал преобразователи типов, описанные здесь (статья на Medium.com), и это сработало:
@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
Пример Kotlin (не хорошо, но просто, 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
}
}
Ответ 6
Вы также должны создать этот TypeConverter
который преобразует ваш List
в 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;
}
И для получения дополнительной информации вы также можете проверить мой другой ответ.
Ответ 7
Была такая же проблема. Измените List
на ArrayList
. Список представляет собой интерфейс, и комната не может его сохранить.
Ответ 8
просто аннотирование этого объекта с помощью @Embedded решило мою проблему. Как это
@Embedded
private List<CrewListBean> crewList;