Reputation: 8208
Error:Not sure how to convert a Cursor to this method's return type
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
Compilation failed; see the compiler error output for details.
Using Room
I'm getting this error and I'd like to find out which method causes it.
I have multiple DAO
s, with approximately 60 methods in total, and this error just popped up after adding a method (copy&pasted from another one that worked perfectly, just changed the field to set).
I could post the whole class of DAO
s, but I'm asking for a way to know which method failed. I tried with Run with --stacktrace
, Run with --info
and --debug option
, but none of these show any valuable information.
The method I added is a @Query
UPDATE
with Int
return type, as suggested in the documentation
UPDATE or DELETE queries can return void or int. If it is an int, the value is the number of rows affected by this query.
EDIT: I'd like to add that I tried deleting the method, bringing the DAO back to the working state, but it still gives me this error.
EDIT2: Adding gradle console output because unreadable in comments:
error: Not sure how to convert a Cursor to this method's return type
error: Not sure how to convert a Cursor to this method's return type
2 errors
:app:compileDebugJavaWithJavac FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:compileDebugJavaWithJavac'.
Compilation failed; see the compiler error output for details.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
* Get more help at https://help.gradle.org
BUILD FAILED in 22s
Upvotes: 123
Views: 94846
Reputation: 2504
Remove suspend keyword From Dio Class,
I Spend the entire day on this issue. the solution was very simple. I was using something like this before
@Query("SELECT * FROM myTable")
fun getAll(): MutableLiveData<ArrayList<myData>>
Now when I changed ArrayList to List & MutableLiveData to LiveData it is working fine.
@Query("SELECT * FROM myTable")
fun getAll(): LiveData<List<myData>>
based on the answers & comments on this issue I think room support only List & LiveData because I tried with on MutableLiveData & only ArrayList too. none of the combinations worked.
Hope this will help someones few hours.
Upvotes: 89
Reputation: 129
Please don't use suspend and LiveData together. I was also getting same error when I'm writing this
@Query(value = "SELECT * FROM saved_articles")
suspend fun getAllSavedArticles() : MutableLiveData<List<Article>>
Also Use LiveData not MutableLiveData. this might also cause an error
@Query(value = "SELECT * FROM saved_articles")
fun getAllSavedArticles() : LiveData<List<Article>>
Upvotes: 0
Reputation: 2871
In my case I started getting the error after upgrading to Kotlin 1.9 and Room 2.5.2. I got solved by switching room compile from kapt to ksp.
Upvotes: 6
Reputation: 197
I faced the same issue when I was implementing the paging 3 library. I solved it by updating my Room dependency version to the latest stable one and also added room-paging support:
implementation "androidx.room:room-paging:$room_version"
Upvotes: 0
Reputation: 1260
I solved this by upgrading my room version
implementation "androidx.room:room-runtime:$roomVersion"
kapt "androidx.room:room-compiler:$roomVersion"
implementation "androidx.room:room-ktx:$roomVersion"
upgrade room version from roomVersion = '2.3.0' to roomVersion = '2.5.2'
Upvotes: 0
Reputation: 11
For my situation, I removed my base Resource class from my Dao, because of it doesn't know how to change the Resource class, and it worked.
Before
fun getAll(): Flow<Resource<List<SavedCharacter>>>
After
fun getAll(): Flow<List<SavedCharacter>>
Upvotes: 0
Reputation: 97
Another reason this might occur is if you try using ArrayList instead of List as it doesn't recognize the return type if it has ArrayList.
for example use:
@Query("SELECT * FROM notificationTable ORDER BY id ASC")
fun getAllNotifications(): LiveData<List<UserNotification>>
instead of
@Query("SELECT * FROM notificationTable ORDER BY id ASC")
fun getAllNotifications(): LiveData<ArrayList<UserNotification>>
Upvotes: 0
Reputation: 1015
There is an issue related to a change in Kotlin's @Metadata
annotation and the way Room reads it, Room 2.4.2
is using an older version of the kotlinx-metadata-jvm
library which does not support reading Kotlin 1.7.x
information, whereas in Room 2.5.0
google updated the library.
To work around this issue please force upgrade the dependency by adding it to your annotation processor path, i.e. add kapt "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0"
if you are using Room 2.4.x
.
or you can use Room 2.5.0-alpha02
it will solve the problem.
if you just want to solve the error add this to app/gradle file
kapt "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0"
or use these versions of room with Kotlin 1.7.x
implementation 'androidx.room:room-ktx:2.5.0-alpha02'
kapt 'androidx.room:room-compiler:2.5.0-alpha02'
Now you can use updating the Room version to Room 2.4.3
with Kotlin 1.7.10
without any problem.
Upvotes: 19
Reputation: 2036
In my case upgrading versions worked.
Previous
api 'androidx.room:room-runtime:2.0.0'
annotationProcessor 'androidx.room:room-compiler:2.0.0'
api 'androidx.room:room-rxjava2:2.0.0'
Now
api 'androidx.room:room-runtime:+'
annotationProcessor 'androidx.room:room-compiler:+'
api 'androidx.room:room-rxjava2:+'
+
means latest version and for me it was 2.4.2
Upvotes: 1
Reputation: 426
It is gone after I updated to latest version Room - room_version = "2.4.0"
Upvotes: 12
Reputation: 237
This error goes away after I changed the Kotlin version from 1.5.21 back to 1.3.61
Upvotes: -1
Reputation: 322
In my case Room didn't know sure how to convert a Cursor to this method's return type i.e ArrayList
so I changed a little bit I converted to list to kotlin's MutableListOf
. Now it works fine.
Upvotes: -1
Reputation: 179
@Query("select * from movie_action")
suspend fun getMovieActionRoom() : LiveData<List<MoviesActionModel>>
just remove suspend and the error will be gone in some cases.
Upvotes: 8
Reputation: 1724
in case someone actually needs MutableLiveData<List<T>>
in their ViewModel when working with Room
and using Kotlin
and coroutines
, this is how I've solved it
In the Dao I get MutableList with suspend
In the repository I change the context to Dispatchers.IO
and extract the list with suspend
in the ViewModel I use postValue
with the list in the init, syntax is below
ViewModel
private val allItems = MutableLiveData<List<DocumentItem>>()
init {
viewModelScope.launch {
allItems.postValue(repository.getAll())
}
}
Repository
suspend fun getAll(): MutableList<DocumentItem> = withContext(Dispatchers.IO) {
dao.getAll()
}
Dao
@Query("SELECT * FROM document_items ORDER BY id DESC")
suspend fun getAll(): MutableList<DocumentItem>
Upvotes: 2
Reputation: 1123
In my case I was using androidx
dependencies for Room
and android.arch.
[old] dependencies for ViewModel
and LiveData
so I got this message
Solution:
Either use all androidx
dependencies OR use all old dependencies of andrio.arch
Upvotes: 3
Reputation: 826
For me it was because of mixing AndroidX with Pre-AndroidX. After a full migration and performing this, everything was back to normal. (Of course I moved to AndroidX-Room as well)
Upvotes: 2
Reputation: 2498
Recently I've had the same problem but I was using Coroutines
within the Dao
function, e.g.:
@Query("SELECT * FROM Dummy")
suspend fun get(): LiveData<List<Dummy>>
And was unable to compile, but after removing the suspend
everything worked just fine. It's not needed when returning LiveData
. suspend
and LiveData
seem not to work together (as of now).
Upvotes: 162
Reputation: 17895
For anyone landing here, using a coroutine Flow as a return type, you will get this error if you accidentally make the function suspend. Since it is returning a flow, there is no need to suspend.
So instead of this:
@Query("SELECT * FROM myTable WHERE id = :id")
suspend fun findById(id: Long): Flow<MyDataType>
use this (without suspend modifier):
@Query("SELECT * FROM myTable WHERE id = :id")
fun findById(id: Long): Flow<MyDataType>
Upvotes: 58
Reputation: 4201
Make sure you are not using suspend together with LiveData as return type:
@Query("SELECT * FROM ...")
fun getAllTellsByReceiver(receiverUid: String): LiveData<List<Tell>>
Upvotes: 1
Reputation: 875
Make sure if there is
There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such table: METRO)
error in your build log before the error you mentioned in your description. If it is, you may have forgotten to add your new entity Pojo to database class. something like this
@Database(entities = {Table.class,ForgottenTable.class}, version = 1)
public abstract class Database extends RoomDatabase {
//class codes
}
Upvotes: 2
Reputation: 1268
I've got a different use case for my apps.
So, I'm trying to return the actual Cursor
type.
E.g:
@Query("SELECT * FROM tbl_favourite")
abstract suspend fun selectAll(): Cursor
The above code will always throw Error:Not sure how to convert a android.database.Cursor to this method's return type
But as I recall correctly, the official docs also stated here that Room supports Cursor
.
After trying to debug the error log, and open up the MyTableDao_Impl.java
file I've found that looks like Cursor
are having an unhealthy relationship with suspend
keywords.
Thus, I've corrected my code to be like this:
@Query("SELECT * FROM tbl_favourite")
abstract fun selectAll(): Cursor
And voila, it works.
Upvotes: 2
Reputation: 565
You have to include the @Relation annotation in the class returned by the method. It's the only way Room would know how to establish the relationship between the two.
Upvotes: 0
Reputation: 36
I got this error when I was trying do some aggregate functions in the query, like sum and count and then using aliases in the column names.
select count(users.id) as userCount, ...
It so happens that the alias name like userCount
above, must match the field name in the model.
Upvotes: -1
Reputation: 2496
For me it was to change from MutableLiveData to LiveData as the return type of the get method.
Upvotes: -1
Reputation: 416
In my case i was this problem when i used LiveData<ArrayList<Example Class>>
in Dao class for getting all things from Room and i fixed this when i change ArrayList
with List
.
Example(Kotlin):
@Dao
interface ExampleDao {
@Query("SELECT * from example_table")
fun getAllExample():LiveData<List<Example>>
}
Upvotes: 6
Reputation: 4524
Modify your Dao, use Flowable instead of observable and add the following dependency (room with rxjava support)
compile group: 'android.arch.persistence.room', name: 'rxjava2', version: '1.1.1'
Dao returns flowable:
@Query("SELECT * FROM TableX")
public abstract Flowable<List<EntityX>> getAllXs();
Upvotes: 0
Reputation: 52484
class IdAndFullName {
public int uid;
@ColumnInfo(name = "full_name")
public String fullName;
}
// DAO
@Query("SELECT uid, name || lastName as full_name FROM user")
public IdAndFullName[] loadFullNames();
If there is a mismatch between the query result and the POJO, Room will give you this error message.
Or if you are using @SkipQueryVerification, you will also get this error.
Upvotes: 0
Reputation: 615
Add the below code inside defaultConfig in build.gradle
javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true
Upvotes: 0