【问题标题】:Android Persistence room: "Cannot figure out how to read this field from a cursor"Android Persistence room:“无法弄清楚如何从光标读取此字段”
【发布时间】: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?

标签: android sqlite android-room android-architecture-components


【解决方案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 中?
猜你喜欢
  • 2022-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 2014-12-20
  • 2013-04-10
  • 1970-01-01
相关资源
最近更新 更多