Search code examples
androidkotlinandroid-room

Room database insert function kotlinx.coroutines.JobCancellationException


I've got some simple code like this:

PlansDao

@Dao
interface PlansDao {

    @Insert(entity = PlanDbo::class)
    suspend fun insertPlan(planDbo: PlanDbo): Long

}

Repository

class PlansRepositoryImpl @Inject constructor(
    private val plansDao: PlansDao
) : PlansRepository {
    override suspend fun writePlan(plan: PlanDbo) {
        Log.d("MAIN_TAG", "start to plansDao.insertPlan(plan): $plan")
        plansDao.insertPlan(plan)
        Log.d("MAIN_TAG", "end of plansDao.insertPlan(plan): $plan")
    }
}

PlanDbo

@Entity(tableName = "plans")
data class PlanDbo(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    @ColumnInfo(name = "name") val name: String,
    @ColumnInfo(name = "start_time") val startTime: String,
    @ColumnInfo(name = "end_time") val endTime: String
)

As you can see, there are two log function lines, the thing is when i call repository.writePlan(plan) (it is called in viewModelScope) the first log message (start of the inserting) shows, but the second one (end of the inserting) never does. Also, the plan object actually appears in the database but sometimes not.

I also tryed this kind of thing with simple DELETE query and the DELETE works completely fine.

What should I do to fix the never-ending insert function?

UPDATE Actually, when I contained plansDao.insertPlan(plan) in try-catch block I got this: W/System.err: kotlinx.coroutines.JobCancellationException: Job was cancelled; and I still can't imagine why it could happen


Solution

  • I've got an answer. It was about viewModelScope. The thing is that I have a screen for adding plans and it has it's own viewModel and when I pressed a button, a viewModelScope.launch{ plansRepository.writePlan(plan) } was called and immediately screen closed. So the viewModel 'died' and it's scope did also. That's why the coroutine was canceled

    The problem was solved by replacing viewModelScope by MainScope but I'm not sure that it is the best scope for this situation