0

I am trying to save the following dao object into a Room database -->

data class JobPW(
    @Embedded val job: Job,
    @Relation(
        parentColumn = "job_id",
        entityColumn = "worker_id",
        associateBy = Junction(JobWorkerCrossRef::class)
    )
    val workers: List<Worker>,

    @Relation(
        entity = Poster::class,
        parentColumn = "job_id",
        entityColumn = "job_id_map"
    )
    val posters: List<PosterWithWorker>
) : Serializable

I was running this code to do it.

   @Transaction
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertJobPW(job: JobPW) : Long {
        val jobId = insertJob(job.job)
        insertWorkers(job.workers)
        job.workers.forEach {
            insertJobWorkerCrossRef(JobWorkerCrossRef(jobId, it.worker_id))
        }
        insertPostersWithWorker(job.posters)
        return jobId
    }

There was no problem with the insertPostersWithWorker function as when I get the object back it is populated with the correct fields. The problem is with the Jobs and Workers cross-reference table.

When I fetch the object the workers aren't there. However, if after I insert the JobPW AND before I fetch it if I try running the insert block

insertJobWorkerCrossRef(JobWorkerCrossRef(jobId, it.worker_id))

from my activity then it works. So my best guess is that it tries to run the above block of code before the job is saved in the database which causes that block to fail.

I've tried to breakdown the code into multiple coroutines with no luck

    override  fun saveJobToDatabase(job : JobPW) : Long {
        var jobId : Long = 0
                PosterPalApplication.applicationScope.launch {
                    launch {
                        jobId = jobsDao.insertJob(job.job)
                    }.invokeOnCompletion {
                        launch {
                            jobsDao.insertPostersWithWorker(job.posters)
                            job.workers.forEach {
                                jobsDao.insertJobWorkerCrossRef(
                                    JobWorkerCrossRef(jobId, it.worker_id)
                                )
                            }
                        }
                    }
                }
        return jobId
    }

What can I do in a suspend function to cause it to wait at a certain point? Any other ideas of what I might be doing wrong?

user1743524
  • 655
  • 1
  • 7
  • 14
  • I found a shitty solution that I wouldn't like to use but it is something that works. I added a callback at the end of the suspend function, SaveJobCallback which runs from the test activity like so --> val jobIdFromDB = repo.saveJobToDatabase(createdJob, object : SaveJobCallback { override fun onJobSaved() { launch { val JobPWFromDB = jobDao.getJobsWithWorkersAndPosters(1000) } } }) This is incorrect right? – user1743524 Mar 21 '23 at 23:43
  • I believe I can create another workaround by using a LiveData wrapper around my getJobsWithPostersAndWorkers function. Perhaps the problem is that I not thinking in a async type of way. I precisely don't want for the UI to wait until it completes the insert. Either way any feedback will be much appreciated! – user1743524 Mar 22 '23 at 01:55

0 Answers0