Android 房间:在继承字段中查询 returns null

Android Room: Query returns null in inherited field

我目前正在重构我的项目以使用 Room Persistence Library(顺便说一句,我很喜欢它),但是我 运行 遇到了一个问题,我正在查询我的数据库以查找继承自的 pojo一个实体-class。 super class 中的字段由于某种原因未加载查询中的数据。

这是我的 class(顺便说一下,这是定制的 class,不是真正的,因为我无法分享真正的源代码):

Task.java:

public class Task extends SyncEntity {

    @PrimaryKey(autoGenerate = true)
    public final long taskId;

    public final String title;

     /** Status of the given task.
     * Enumerated Values: 0 (Active), 1 (Inactive), 2 (Completed)
     */
    @TypeConverters(StatusConverter.class)
    public final Status status;

    @TypeConverters(DateConverter.class)
    public Date startDate;

    public Task(@NonNull String taskId,
                   @NonNull String title,
                   @NonNull Status status,
                   @NonNull Date startDate,
                   @NonNull Long createdAt,
                   @Nullable Long updatedAt,
                   @Nullable Boolean deleted) {
        super(createdAt, updatedAt, deleted);
        this.taskId = taskId;
        this.title = title;
        this.status = status;
    }

    @Ignore
    public Task(@NonNull Builder builder) {
        super(builder);
        this.taskId = builder.taskId;
        this.title = builder.title;
        this.status = builder.status;
    }

    ...
    ** left out for brevity **

}

我的查询:

@Dao
public interface TaskRepository {

    @Query("SELECT " +
            "taskId, " +
            "title, " +
            "status, " +
            "startDate, " +
            "created_at AS createdAt, " +
            "updated_at AS updatedAt " +
            "FROM tasks " +
            "WHERE status = 0 " +
            "AND deleted = 0")
    LiveData<List<Task>> getActiveTasks();
    ...
    ** left out for brevity **
}

查询 return createdAt 为 null 的结果,它不应该是 null,因为所有 SyncEntities 默认 createdAt 为 System.currentTimeMillis() 并且我已经仔细检查了该值是否存在于数据库。

我在编译的时候也出现了下面的警告,但是我不明白为什么:

Warning:(33, 33) The query returns some columns [createdAt, updatedAt] which are not use by com.example.project.data.models.entities.Task. You can use @ColumnInfo annotation on the fields to specify the mapping. com.example.project.data.models.entities.Task has some fields [created_at, updated_at, deleted] which are not returned by the query. If they are not supposed to be read from the result, you can mark them with @Ignore annotation. You can suppress this warning by annotating the method with @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH). Columns returned by the query: taskId, title, status, startDate, createdAt, updatedAt. Fields in com.example.project.data.models.entities.Task: created_at, updated_at, deleted, taskId, title, status, startDate.

这是我的超级class: SynEntity.java

@Entity
public class SyncEntity implements Syncable {

    @NonNull
    @ColumnInfo(name = "created_at")
    public final Long createdAt;

    @Nullable
    @ColumnInfo(name = "updated_at")
    public final Long updatedAt;

    @Nullable
    public final Boolean deleted;

    SyncEntity(@NonNull Long createdAt,
               @Nullable Long updatedAt,
               @Nullable Boolean deleted) {
            this.createdAt = createdAt;
            this.updatedAt = updatedAt;
            this.deleted = deleted == null ? false : deleted;
    }

    @Ignore
    SyncEntity(@NonNull Builder<?> builder) {
            this.createdAt = builder.createdAt;
            this.updatedAt = builder.updatedAt;
            this.deleted = builder.deleted;
    }

    public static class Builder<T extends Builder<T>> {

        @NonNull
        private Long createdAt = System.currentTimeMillis();
        @Nullable
        private Long updatedAt = null;
        @NonNull
        private Boolean deleted = false;

        public Builder() {}

    ...
    ** left out for brevity **

}

这是 Room 中的错误还是预期的行为?

编辑 正如@pskink 在评论中指出的那样,问题出在查询上。

问题出在查询中:

@Override
public LiveData<List<UserPet>> loadUserAndPetNames() {
    final String _sql = "SELECT users.firstName AS firstName, 
    users.lastName AS lastName, pets.name AS petName, pets.created_at 
    AS createdAt, pets.updated_at AS updatedAt, pets.deleted AS deleted 
    FROM users, pets WHERE users.userId = pets.user_id";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);

查询 returns 列名称为 "createdAt",但实体的字段显式注释为 "created_at",因此它们不匹配。