Error using dao class when using Kotlin coroutines

I am trying to use kotlin coroutines to access the database in the database using the method described below, a plugin and dependency are added and kotlin coroutines is included in gradle.

in gradle file:

kotlin { experimental { coroutines 'enable' } } dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.21" ...} 

So, I added the suspend keyword for all methods in the dao class, for example:

dao class

 @Query("select * from myevent") suspend fun all(): List<MyEvent> @Delete suspend fun deleteEvent(event: MyEvent) ... 

and build, then get these errors

Mistake

e: C:\Users\projectpath\app\build\tmp\kapt3\stubs\debug\com\robyn\myapp\data\source\local\EventsDao.java:39: error: Deletion methods must either return void or return int (the number of deleted rows). public abstract java.lang.Object deleteEventById(@org.jetbrains.annotations.NotNull() ^ e: C:\Users\projectpath\app\build\tmp\kapt3\stubs\debug\com\robyn\myapp\data\source\local\EventsDao.java:41: error: Query method parameters should either be a type that can be converted into a database column or a List / Array that contains such type. You can consider adding a Type Adapter for this. kotlin.coroutines.experimental.Continuation<? super kotlin.Unit> p1);

error links go to the automatically generated dao class. The created methods in this class now have an additional parameter of this type Continuation , since this:

auto-generated dao class

 @org.jetbrains.annotations.Nullable() @android.arch.persistence.room.Delete() public abstract java.lang.Object deleteAllEvents(@org.jetbrains.annotations.NotNull() // error indicates at this line java.util.List<com.robyn.myapp.data.MyEvent> events, @org.jetbrains.annotations.NotNull() kotlin.coroutines.experimental.Continuation<? super kotlin.Unit> p1); // error indicates at this line ... 

I tried deleting the generated dao class and rebuilding to renounce it, still get these errors. I believe that you do not use the lauch{} method, but use the suspend keyword, because there are many places in the code for the db request.

How can i fix this?

+6
coroutine android kotlin android-room
source share
1 answer

You cannot use suspend methods for DAO. The suspension function is processed at compile time, and the compiler changes the signature of this function (another type of return value, an additional argument for the state machine callback) to make it non-blocking.

The room is waiting for the signature of a specific method to generate code. Thus, as long as Room does not support coroutines directly, you cannot use the pause function for DAO.

At the moment, you have these workarounds:

  1. If the DAO method returns a value, use RxJava or LiveData to get it and use the coroutine adapter for RxJava or write your own for LiveData (I donโ€™t know the existing ones)
  2. Wrap a synchronous call to the DAO method in a coroutine with its own thread pool (because such a call will block).

But always prefer option 1, if possible, because Room already provides a non-blocking API, just use the coroutine adapter to allow this API to be used with coroutines without callbacks

Starting with Room 2.1.0-alpha03 , DAO methods can now be suspend . Dao methods specifically marked as @Insert, @Update, or @Delete may be suspended by functions. Insertions, updates, and deletions marked as @Query are not yet supported, although regular queries are supported. For more information, see: Architectural Component Release Notes and Feature Request .

+4
source share

All Articles