エラーのため、部屋に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})を置くとエラーが発生し続けます。しかし、公式には、typeConverterを登録するために注釈を配置した場所です。
@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.
これは、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のバージョンを更新してください。残りの設定は正しいものです。ルームの永続化作業の残りの部分でハッピーハンティング。
同じエラーが発生しました:「日付フィールドを追加しようとしたときに、このフィールドをデータベースに保存する方法がわかりません」。そのためのコンバータクラスを追加し、@ 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();
}
}
@TypeConverter
はList
クラスを認識しないため、代わりにArrayList
を使用する必要があります。したがって、永続化するリストに追加のラッパーは必要ありません。
ここ(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);
}
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
}
}
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;
}
また、詳細については、別の answer を確認することもできます。
同じ問題がありました。 List
をArrayList
に変更します。リストはインターフェースであり、部屋はそれを保存できません。