2017-06-19 58 views
1

我愿意从Android尝试新的室图书馆和我遇到下面的错误:错误试图缓存采用Android室图书馆一个HashSet

Error:(19, 29) error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.

此错误是指下列类成员:

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类:

因为我想成为一个很好的开发者,我写了一个单元测试如下:

@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()); 
} 

我应该怎么做吗?

回答

1

What should I do here?

您可以创建一个type converter,该错误信息的建议。房间不知道如何坚持HashSet<String>Restaurant或其他任意物体。

第1步:确定要将HashSet<String>转化成哪些基本类型(例如,一个String

第2步:写有public static类型转换方法的类,有@TypeConverter注释,做转换(例如,HashSet<String>StringStringHashSet<String>),在某些安全的方式(例如,使用GSON,格式化你的String作为JSON)

第3步:一@TypeConverters注释添加到您的RoomDatabase或其他范围,教室关于你的@TypeConverter种方法

例如,这里有对类型的转换器的方法,用于从规则String转换Set<String>到/,使用JSON作为String的格式。

@TypeConverter 
    public static String fromStringSet(Set<String> strings) { 
    if (strings==null) { 
     return(null); 
    } 

    StringWriter result=new StringWriter(); 
    JsonWriter json=new JsonWriter(result); 

    try { 
     json.beginArray(); 

     for (String s : strings) { 
     json.value(s); 
     } 

     json.endArray(); 
     json.close(); 
    } 
    catch (IOException e) { 
     Log.e(TAG, "Exception creating JSON", e); 
    } 

    return(result.toString()); 
    } 

    @TypeConverter 
    public static Set<String> toStringSet(String strings) { 
    if (strings==null) { 
     return(null); 
    } 

    StringReader reader=new StringReader(strings); 
    JsonReader json=new JsonReader(reader); 
    HashSet<String> result=new HashSet<>(); 

    try { 
     json.beginArray(); 

     while (json.hasNext()) { 
     result.add(json.nextString()); 
     } 

     json.endArray(); 
    } 
    catch (IOException e) { 
     Log.e(TAG, "Exception parsing JSON", e); 
    } 

    return(result); 
    } 
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(); 
    } 

} 
+1

请注意,这只有在单个字符串本身不使用''''时才有效。否则,除了用作列表分隔符的那些外,你的'split()'调用将把这些单独的字符串分割为它们的','字符。我添加了一些代码给我的答案,显示使用JSON,它应该能够处理任意字符串(虽然它比你的解决方案更详细)。 – CommonsWare