2

i am inserting and deleting a row in room database using following methods of ViewModel class

fun insert(rules: TableRules) = viewModelScope.launch {
    repository.insert(rules)
}

fun delete(id: Int) = viewModelScope.launch {
    repository.delete(id)
}

and retriving the data using this this method of DAO class

@Query("SELECT * FROM rules_table")
fun getAlphabetizedRules(): List<TableRules>

but i am not getting update data. i.e when i add one row and then retrive, i will not get newly added row. i close my app, remove from recent app list, start app again then retrive, then i will get that row.

same thing happens in case of delete also.

what i am missing i above.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Jignesh Ansodariya
  • 12,583
  • 24
  • 81
  • 113
  • I would guess that you launch `getAlphabetizedRules` right after `insert` and since you're using a launch coroutine, the insertion may be not yet finished when you try to retrieve the data. Either make sure that your insertion is finished or use a flow with Room to get your data as soon as it changes. – bcordier Apr 21 '22 at 14:04
  • @bcordier i think it is not case of concorancy, as I waited 5 minuts after insertion operation and then retrived, still issue. but when i removed app from recent apps list and start again it worked as expected – Jignesh Ansodariya Apr 22 '22 at 07:58
  • use ``Flow>`` as soon as you make the changes in your db flow will throw the newly added value. – USMAN osman Apr 26 '22 at 12:04
  • did you get the solution to this issue? I'm facing a similar issue like yours... my SELECT query always return the default value for boolean column. The data is updated when I look at it through database inspector, but for some reason, when I queried it, it will always return false (the default value) – imin Sep 19 '22 at 15:31

2 Answers2

1

Launching a coroutine queues up work that will complete in the future. If you launch a coroutine and then immediately check the state of the table without waiting for the coroutine to finish, you have a race condition and will likely get the earlier state returned.

You need to call getAlphabetizedRules() from inside the same coroutine that you launch to call insert() or delete() so it is happening after the database change.

Or alternatively, you can create a new coroutine or suspend function that joins the returned Job from your existing insert() and delete() functions. For example:

suspend fun deleteAndGetUpdatedList(id: Int): List<TableRules> {
    delete(id).join()
    return repository.getAlphabetizedRules()
}

By the way, in your DAO, getAlphabetizedRules() should be marked as a suspend function to make it easier to use properly (not having to use withContext(Dispatchers.IO) { } every time you call it.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • I think it is not case of concorancy, as I waited 5 minuts after insertion operation and then retrived, still issue. but when i removed app from recent apps list and start again it worked as expected – Jignesh Ansodariya Apr 22 '22 at 08:01
0

Mark the DAO method with @RawQuery annotation instead of normal @Query.

Kamran Khan
  • 408
  • 2
  • 10