Android room persistent library - TypeConverter错误错误:无法弄清楚如何将字段保存到数据库"

j2e*_*nue 30 android android-room

由于错误,我无法在房间内创建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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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);
}}
Run Code Online (Sandbox Code Playgroud)

然后问题是我把@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();
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

Error:(58, 31) error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
Run Code Online (Sandbox Code Playgroud)

Jac*_*ton 29

自从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;
    }
}
Run Code Online (Sandbox Code Playgroud)

此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;
    }
}
Run Code Online (Sandbox Code Playgroud)

此转换器获取字符串列表并将其转换为逗号分隔字符串以存储在单个列中.当它从SQLite数据库中获取字符串以进行转换时,它会在逗号上拆分列表,并填充CountryLangs.

确保在进行这些更改后更新RoomDatabase版本.您可以正确配置其余配置.快乐的狩猎与你房间的其余部分坚持工作.


liv*_*ove 17

在尝试添加Date字段时遇到同样的错误:"无法弄清楚如何将此字段保存到数据库中".必须为它添加转换器类并将@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;
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,我还必须按照 Google 的文章将 `@TypeConverters(DateConverter.class)` 添加到房间数据库类:https://developer.android.com/training/data-storage/room/referencing-data (4认同)

Abh*_*mal 11

以防万一您需要更清晰的信息。

首先创建一个转换器通用类,如下所示。

class Converters {

@TypeConverter
fun fromGroupTaskMemberList(value: List<Comment>): String {
    val gson = Gson()
    val type = object : TypeToken<List<Comment>>() {}.type
    return gson.toJson(value, type)
}

@TypeConverter
fun toGroupTaskMemberList(value: String): List<Comment> {
    val gson = Gson()
    val type = object : TypeToken<List<Comment>>() {}.type
    return gson.fromJson(value, type)
}
Run Code Online (Sandbox Code Playgroud)

}

然后在数据库类中添加这个转换器,就像,

@TypeConverters(Converters::class)
Run Code Online (Sandbox Code Playgroud)

抽象类 AppDatabase : RoomDatabase() {


Mor*_*rZa 7

我使用了此处描述的类型转换器(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);
    }
Run Code Online (Sandbox Code Playgroud)

  • 在字段中缓存 `new Gson`。这是一个沉重的对象,需要很长时间才能创建,您不想每次调用转换器时都创建一个新实例。类型标记也是如此。 (3认同)

Liy*_*iya 7

只需用 @Embedded 注释该对象就解决了我的问题。像这样

@Embedded
private List<CrewListBean> crewList;
Run Code Online (Sandbox Code Playgroud)


sou*_*dit 6

我可能会迟到回答,但是。我有一些简单的解决方案,我正在共享处理一些基本要求的TypeConverter调用

class RoomConverters {
//for date and time convertions
@TypeConverter
fun calendarToDateStamp(calendar: Calendar): Long = calendar.timeInMillis

@TypeConverter
fun dateStampToCalendar(value: Long): Calendar =
    Calendar.getInstance().apply { timeInMillis = value }

//list of cutome object in your database
@TypeConverter
fun saveAddressList(listOfString: List<AddressDTO?>?): String? {
    return Gson().toJson(listOfString)
}

@TypeConverter
fun getAddressList(listOfString: String?): List<AddressDTO?>? {
    return Gson().fromJson(
        listOfString,
        object : TypeToken<List<String?>?>() {}.type
    )
}

/*  for converting List<Double?>?  you can do same with other data type*/
@TypeConverter
fun saveDoubleList(listOfString: List<Double>): String? {
    return Gson().toJson(listOfString)
}

@TypeConverter
fun getDoubleList(listOfString: List<Double>): List<Double> {
    return Gson().fromJson(
        listOfString.toString(),
        object : TypeToken<List<Double?>?>() {}.type
    )
}

// for converting the json object or String into Pojo or DTO class
@TypeConverter
fun toCurrentLocationDTO(value: String?): CurrentLocationDTO {
    return  Gson().fromJson(
        value,
        object : TypeToken<CurrentLocationDTO?>() {}.type
    )
}

@TypeConverter
fun fromCurrentLocationDTO(categories: CurrentLocationDTO?): String {
    return Gson().toJson(categories)

}

}
Run Code Online (Sandbox Code Playgroud)

您必须编写自己的类并在此处进行解析,然后将其添加到您的 AppDatabase 类中

@Database(
        entities = [UserDTO::class],
        version = 1, exportSchema = false
         ) 
@TypeConverters(RoomConverters::class)
@Singleton
abstract class AppDatabase : RoomDatabase() {
Run Code Online (Sandbox Code Playgroud)


Edu*_*kis 5

@TypeConverter不能识别List类,因此应改用类,这样ArrayList就不需要为要保留的列表使用其他包装。

  • 我们还需要其他配置吗?我将“List”更改为“ArrayList”,但仍然收到“错误:无法弄清楚如何将此字段保存到数据库中”。您可以考虑为其添加类型转换器。私有 java.util.ArrayList&lt;java.lang.String&gt; notificationTypes; ^` (4认同)