Android Persistence room:“无法弄清楚如何从光标读取此字段”

Posted

技术标签:

【中文标题】Android Persistence room:“无法弄清楚如何从光标读取此字段”【英文标题】:Android Persistence room: "Cannot figure out how to read this field from a cursor" 【发布时间】:2017-11-03 22:55:13 【问题描述】:

我正在尝试使用新的 android Persistence Room Library 在两个数据库表之间创建关系。我查看了文档并尝试实现在https://developer.android.com/reference/android/arch/persistence/room/Relation.html 找到的示例:

 @Entity
 public class User 
 @PrimaryKey
     int id;
 

 @Entity
 public class Pet 
     @PrimaryKey
     int id;
     int userId;
     String name;

 

 @Dao
 public interface UserDao 
     @Query("SELECT * from User")
     public List<User> loadUser();
 

 @Dao
 public interface PetDao 
     @Query("SELECT * from Pet")
     public List<Pet> loadUserAndPets();
 


 public class UserAllPets 
     @Embedded
     public User user;
     @Relation(parentColumn = "user.id", entityColumn = "userId", entity = Pet.class)
     public List pets;
 

 @Dao
 public interface UserPetDao 
     @Query("SELECT * from User")
     public List<UserAllPets> loadUserAndPets();
 

我收到以下错误

    ...error: Cannot figure out how to read this field from a cursor.

关于:

 private java.util.List<?> pets;

我想指出,我发现他们文档中的某些内容确实令人困惑。例如缺少@PrimaryKey 以及User 类缺少@Entity 注释的事实,尽管它应该是一个实体(据我所知)。有人遇到同样的问题吗?提前非常感谢

【问题讨论】:

private java.util.List&lt;?&gt; ingredients; 出现在图片中。您的代码粘贴正确了吗? @Moinkhan 它应该是“宠物”对不起。成分来自另一个例子,我正在做同样的事情并得到同样的错误...... 你试过public List;并且没有在关系行中定义 entity = Pet.class? 【参考方案1】:

Document 真是令人困惑。试试下面的类:

1) 用户实体:

@Entity
public class User 
    @PrimaryKey
    public int id; // User id

2) 宠物实体:

@Entity
public class Pet 
    @PrimaryKey
    public int id;     // Pet id
    public int userId; // User id
    public String name;

3) UserWithPets POJO:

// Note: No annotation required at this class definition.
public class UserWithPets 
   @Embedded
   public User user;

   @Relation(parentColumn = "id", entityColumn = "userId", entity = Pet.class)
   public List<Pet> pets; // or use simply 'List pets;'


   /* Alternatively you can use projection to fetch a specific column (i.e. only name of the pets) from related Pet table. You can uncomment and try below;

   @Relation(parentColumn = "id", entityColumn = "userId", entity = Pet.class, projection = "name")
   public List<String> pets; 
   */

parentColumn 指的是嵌入式User 表的id 列, entityColumn 指的是Pet 表的userId (User - Pet 关系) 列, entity 指的是与User 表有关系的表(Pet)。

4) UserDao 道:

@Dao
public interface UserDao 
    @Query("SELECT * FROM User")
    public List<UserWithPets> loadUsersWithPets();

现在试试loadUsersWithPets(),它会返回用户及其宠物列表。

编辑:请参阅我的other answer 了解许多关系。

【讨论】:

@DevrimTuncer @AndreaSoro 我们如何插入UserWithPet?文档说 Room 要求插入是 Entity 或它的集合/数组,所以我们不能直接插入 UserWithPet @AkshayChordiya 我遇到了同样的错误——但是:如果你使用 LiveData 来更新你的 UI,你只需要编写两个不同的 DAO(在这种情况下是 Pet 和 User),然后就可以了只需在pet-dao中插入pet,在user-dao中插入用户,然后从User-Dao中获取PetWithUser-Entities。宠物也会出现。 所以你需要一个 UserWithPets 风格的类来处理每一个关系?我知道延迟加载在移动设备上很危险,但这不是矫枉过正吗?他们不能只放一个@NoLazyLoading 属性,有点像实体框架,如果您的方法属性不是虚拟的,默认情况下不会延迟加载? 很好的答案!虽然有一件事困扰着我。为什么不将关系字段放入用户实体本身?我的意思是,为什么我们需要带有嵌入式实体的单独 pojo 类? 在第 4 步中,SELECT * FROM User 查询如何让您返回 List&lt;UserWithPets&gt;(而不仅仅是 List&lt;User&gt;)?是不是因为在第 3 步中,我们将 User 嵌入到了 UserWithPets 中?

以上是关于Android Persistence room:“无法弄清楚如何从光标读取此字段”的主要内容,如果未能解决你的问题,请参考以下文章

从 SQLite 迁移到 Android Room Persistence Library

Android Persistence room:“无法弄清楚如何从光标读取此字段”

如何使用 Android Room Persistence Library 将 Column 注释为 NOT NULL

Android Room框架学习笔记

Android Room Persistence Library - 如何查找 ID 列表中包含 ID 的实体?

调用 Rooms inMemoryBuilder 方法时,Room Persistence Library 运行时异常