Room Livedata возвращает неверные значения - PullRequest
0 голосов
/ 16 марта 2020

У меня есть приложение для записи звука, где я позволяю пользователю отмечать определенные точки в своих записях заранее определенными маркерами. Для этого у меня есть MarkerEntity, который является типом Marker, и MarkTimestamp, точка, в которой пользователь отмечает данную запись. Эти объекты связаны через Relation, называемый MarkAndTimestamp.

@Entity(tableName = "markerTable")
data class MarkerEntity(
    @PrimaryKey(autoGenerate = true) val uid: Int,
    @ColumnInfo(name = "markerName") val markerName: String
)

@Entity(tableName = "markerTimeTable")
data class MarkTimestamp(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "mid") val mid: Int,
    @ColumnInfo(name = "recordingId") val recordingId: Int,
    @ColumnInfo(name = "markerId") val markerId: Int,
    @ColumnInfo(name = "markTime") val markTime: String
)

data class MarkAndTimestamp(
    @Embedded val marker: MarkerEntity,
    @Relation(
        parentColumn = "uid",
        entityColumn = "markerId"
    )
    val markTimestamp: MarkTimestamp
)

Вставка этих данных работает безупречно, я проверил это через DB Browser для SQLite и Android Debug Database. Проблема возникает, когда я хочу отобразить все отметки для записи. Я извлекаю записи с помощью следующего оператора SQL.

@Transaction
@Query("SELECT * FROM markerTimeTable INNER JOIN markerTable ON markerTimeTable.markerId=markerTable.uid WHERE markerTimeTable.recordingId = :key")
fun getMarksById(key: Int): LiveData<List<MarkAndTimestamp>>

В конечном итоге происходит следующее: если пользователь использует маркер более одного раза, все метки, созданные с помощью этого маркера, имеют одну и ту же строку MarkerTimestamp. им, в частности, последняя строка, которая будет вставлена ​​с этим маркером. Странно то, что это происходит только в приложении с использованием Livedata. Использование того же запроса в DB Browser для SQLite возвращает правильные и нужные данные.

Это сохраненные данные (правильные)

MarkTimestamps

MarkerEntities

И это Livedata, возвращенные в данный момент (неверно)

[
MarkAndTimestamp(marker=MarkerEntity(uid=1, markerName=Mark), markTimestamp=MarkTimestamp(mid=6, recordingId=2, markerId=1, markTime=00:05)),
MarkAndTimestamp(marker=MarkerEntity(uid=2, markerName=zwei), markTimestamp=MarkTimestamp(mid=5, recordingId=2, markerId=2, markTime=00:03)),
MarkAndTimestamp(marker=MarkerEntity(uid=1, markerName=Mark), markTimestamp=MarkTimestamp(mid=6, recordingId=2, markerId=1, markTime=00:05))
]

Я также получаю следующее предупреждение о сборке

warning: The query returns some columns [mid, recordingId, markerId, markTime] which are not used by de.ur.mi.audidroid.models.MarkAndTimestamp. You can use @ColumnInfo annotation on the fields to specify the mapping.  You can suppress this warning by annotating the method with @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH). Columns returned by the query: mid, recordingId, markerId, markTime, uid, markerName. Fields in de.ur.mi.audidroid.models.MarkAndTimestamp: uid, markerName. - getMarksById(int) in de.ur.mi.audidroid.models.MarkerDao

Почему Room возвращает неверные данные и как это исправить?

1 Ответ

0 голосов
/ 18 марта 2020

Итак, я до сих пор не знаю, что вызвало поведение, описанное в моем исходном посте. Я полагаю, что класс данных реализаций и запрос SQL каким-то образом вмешались, что привело к неправильному результату.

Тем не менее я решил свою проблему. Мне нужно было изменить

data class MarkAndTimestamp(
    @Embedded val marker: MarkerEntity,
    @Relation(
        parentColumn = "uid",
        entityColumn = "markerId"
    )
    val markTimestamp: MarkTimestamp
)

на

data class MarkAndTimestamp(
    @Embedded val marker: MarkerEntity,
    @Embedded val markTimestamp: MarkTimestamp
)

. Это гарантирует, что все поля, возвращаемые запросом, включены в класс данных.

...