尝试使用Android Room Library缓存HashSet时出错

时间:2017-06-19 14:58:19

标签: android android-room

我愿意尝试使用Android的新房间库,我遇到了以下错误:

  

错误:(19,29)错误:无法弄清楚如何将此字段保存到   数据库。你可以考虑为它添加一个类型转换器。

此错误引用以下类成员:

private HashSet<String> fruits;

我有以下课程:

@Entity(tableName = "SchoolLunches")
public class SchoolLunch {

    @PrimaryKey(autoGenerate = true)
    private int lunchId;

    private boolean isFresh;

    private boolean containsMeat;

    private HashSet<String> fruits;

    public int getLunchId() {
        return lunchId;
    }

    public void setLunchId(int lunchId) {
        this.lunchId = lunchId;
    }

    public boolean isFresh() {
        return isFresh;
    }

    public void setFresh(boolean fresh) {
        isFresh = fresh;
    }

    public boolean isContainsMeat() {
        return containsMeat;
    }

    public void setContainsMeat(boolean containsMeat) {
        this.containsMeat = containsMeat;
    }

    public HashSet<String> getFruits() {
        return fruits;
    }

    public void setFruits(HashSet<String> fruits) {
        this.fruits = fruits;
    }

此外,还有一个相对DAO类:

@Dao
public interface SchoolLunchDAO {

    @Query("SELECT * FROM SchoolLunches")
    List<SchoolLunch> getAll();

    @Insert
    void insertAll(SchoolLunch... schoolLunches);

    @Query("DELETE FROM SchoolLunches")
    void deleteAll();
}

因为我想成为一名优秀的开发人员,所以我写了一个单元测试如下:

@Test
public void singleEntityTest() {
        HashSet<String> fruitSet = new HashSet<>();
        fruitSet.add("Apple");
        fruitSet.add("Orange");

        SchoolLunch schoolLunch = new SchoolLunch();
        schoolLunch.setContainsMeat(false);
        schoolLunch.setFresh(true);
        schoolLunch.setFruits(fruitSet);

        schoolLunchDAO.insertAll(schoolLunch);

        List<SchoolLunch> schoolLunches = schoolLunchDAO.getAll();
        assertEquals(schoolLunches.size(), 1);

        SchoolLunch extractedSchoolLunch = schoolLunches.get(0);
        assertEquals(false, extractedSchoolLunch.isContainsMeat());
        assertEquals(true, extractedSchoolLunch.isFresh());
        assertEquals(2, extractedSchoolLunch.getFruits().size());
 }

我该怎么办?

2 个答案:

答案 0 :(得分:1)

  

我该怎么办?

您可以根据错误消息的建议创建type converter。 Room不知道如何保留HashSet<String>Restaurant或其他任意对象。

步骤1:确定要将HashSet<String>转换为哪种基本类型(例如,String

步骤2:使用public static类型转换方法编写一个带有@TypeConverter注释的类来进行转换(例如,HashSet<String>String,{{1以某种安全的方式(例如,使用Gson,将String格式化为JSON)

第3步:在HashSet<String>或其他范围添加String注释,向教室介绍您的@TypeConverters方法

例如,以下是一对类型转换器方法,用于将RoomDatabase转换为常规@TypeConverter,使用JSON作为Set<String>的格式。

String

答案 1 :(得分:0)

我创建了以下类,现在它可以工作了。谢谢你,CommonsWare!

public class Converters {

    private static final String SEPARATOR = ",";

    @TypeConverter
    public static HashSet<String> fromString(String valueAsString) {
        HashSet<String> hashSet = new HashSet<>();
        if (valueAsString != null && !valueAsString.isEmpty()) {
            String[] values = valueAsString.split(SEPARATOR);
            hashSet.addAll(Arrays.asList(values));
        }
        return hashSet;
    }

    @TypeConverter
    public static String hashSetToString(HashSet<String> hashSet) {
        StringBuilder stringBuilder = new StringBuilder();
        for (String currentElement : hashSet) {
            stringBuilder.append(currentElement);
            stringBuilder.append(SEPARATOR);
        }
        return stringBuilder.toString();
    }

}