Bohsen
Bohsen

Reputation: 4350

Android Room: Query returns null in inherited field

I'm currently refactoring my project to use Room Persistence Library (loving it by the way), but I've run into a problem where I'm querying my database for a pojo that inherits from an Entity-class. The fields in the super class is for some reason not being loaded with data from the query.

Heres my class (btw. this is a customized class, not the real one, as I can't share the real sourcecode):

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 **

}

and my query:

@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 **
}

The query return a result where createdAt is null, which it shouldn't be, as all SyncEntities defaults createdAt to System.currentTimeMillis() and I've doublechecked that the value is present in the database.

I'm also getting the following warning when compiling, but I don't understand why:

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.

Here's my super-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 **

}

Is this a bug in Room or intended behavior?

Upvotes: 0

Views: 3254

Answers (1)

Bohsen
Bohsen

Reputation: 4350

EDIT As @pskink pointed out in the comments, the problem is the query.

The problem lies in the query:

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

The query returns column name as "createdAt" but the Entity's field is explicitly annotated with "created_at" so they don't match.

Upvotes: 2

Related Questions