Room "Not sure how to convert a Cursor to this method's return type": 哪个方法?

Room "Not sure how to convert a Cursor to this method's return type": which method?

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.

使用 Room 我遇到了这个错误,我想找出导致它的方法。

我有多个DAO,总共有大约60个方法,添加一个方法后就弹出这个错误(从另一个完美运行的方法复制粘贴,只是将字段更改为设置)。

我可以 post DAO 的整个 class,但是 我想知道哪个方法失败了 .我尝试使用 Run with --stacktraceRun with --info--debug option,但其中 none 显示了任何有价值的信息。

我添加的方法是 @Query UPDATEInt return 类型,如 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.

编辑:我想补充一点,我尝试删除该方法,使 DAO 恢复到工作状态,但它仍然给我这个错误。

EDIT2:添加 gradle 控制台输出,因为在注释中不可读:

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

是的,根据您在评论中提到的内容,您不能将 return 类型从 List 更改为 Dao 中的任何其他类型。我假设 Room 不知道如何处理其他 return 类型。将 List 和 cast/convert 放入 Dao.

之外的所需类型

对于我的情况,在收到“不确定如何将 Cursor 转换为该方法的 return 类型”之后:

删除"build"并重新构建,错误消失。

在 build.gradle

的 defaultConfig 中添加以下代码
javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true
 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();

如果查询结果与 POJO 不匹配,Room 会给你这个错误信息。

或者如果你使用@SkipQueryVerification,你也会得到这个错误。

修改你的 Dao,使用 Flowable 而不是 observable 并添加以下依赖项(支持 rxjava 的空间)

compile group: 'android.arch.persistence.room', name: 'rxjava2', version: '1.1.1'

Dao returns 可流动:

@Query("SELECT * FROM TableX")
public abstract Flowable<List<EntityX>> getAllXs();

在我的例子中,当我在 Dao class 中使用 LiveData<ArrayList<Example Class>> 从 Room 获取所有东西时,我遇到了这个问题,当我将 ArrayList 更改为 [=13= 时,我解决了这个问题].

示例(Kotlin):

@Dao
interface ExampleDao {
@Query("SELECT * from example_table")
fun getAllExample():LiveData<List<Example>>
}

对我来说,这是因为混合了 AndroidX 和 Pre-AndroidX。在完全迁移和 之后,一切恢复正常。 (当然我也搬到了AndroidX-Room)

对我来说,是将 MutableLiveData 更改为 LiveData 作为 get 方法的 return 类型。

对我来说,我使用了错误的 return 查询类型。

当我尝试在查询中执行一些聚合函数时遇到此错误,例如求和和计数,然后在列名称中使用别名。

select count(users.id) as userCount, ...

碰巧像上面userCount这样的别名,必须匹配模型中的字段名。

我在这个问题上花了一整天。解决方案非常简单。我以前用过类似的东西

@Query("SELECT * FROM myTable")
fun getAll(): MutableLiveData<ArrayList<myData>>

现在,当我将 ArrayList 更改为 List 并将 MutableLiveData 更改为 LiveData 时,它工作正常。

@Query("SELECT * FROM myTable")
fun getAll(): LiveData<List<myData>>

根据对这个问题的回答和评论,我认为房间仅支持 List 和 LiveData,因为我也尝试使用 MutableLiveData 和仅 ArrayList。 none 的组合有效。

希望这能帮助一些人几个小时。

您必须在方法返回的 class 中包含 @Relation 注释。这是 Room 知道如何在两者之间建立关系的唯一方式。

最近我遇到了同样的问题,但我在 Dao 函数中使用了 Coroutines,例如:

@Query("SELECT * FROM Dummy")
suspend fun get(): LiveData<List<Dummy>>

并且无法编译,但是在 删除 suspend 之后一切正常。返回 LiveData 时不需要它。 suspendLiveData 似乎不能一起工作(截至目前)。

我的应用有不同的用例。

所以,我正在尝试 return 实际的 Cursor 类型。

例如:

@Query("SELECT * FROM tbl_favourite")
abstract suspend fun selectAll(): Cursor

上面的代码总是会抛出Error:Not sure how to convert a android.database.Cursor to this method's return type

但我没记错的话,官方文档还指出 here Room 支持 Cursor.

在尝试调试错误日志并打开 MyTableDao_Impl.java 文件后,我发现 Cursor 似乎与 suspend 关键字有不正常的关系。

因此,我将我的代码更正为:

@Query("SELECT * FROM tbl_favourite")
abstract fun selectAll(): Cursor

瞧,它起作用了。

确定是否有

There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such table: METRO)


在您在描述中提到的错误之前,构建日志中的错误。如果是,您可能忘记将新实体 Pojo 添加到数据库 class。像这样

@Database(entities = {Table.class,ForgottenTable.class}, version = 1) 
public abstract class Database extends RoomDatabase {
    //class codes
}

确保您没有将挂起与 LiveData 一起使用,因为 return 类型:

@Query("SELECT * FROM ...")
fun getAllTellsByReceiver(receiverUid: String): LiveData<List<Tell>>

对于登陆这里的任何人,使用 coroutine Flow 作为 return 类型,如果您不小心使函数挂起,您将收到此错误。由于它是 returning 流,因此无需暂停。

所以不是这个:

@Query("SELECT * FROM myTable WHERE id = :id")
suspend fun findById(id: Long): Flow<MyDataType>

使用这个(没有暂停修饰符):

@Query("SELECT * FROM myTable WHERE id = :id")
fun findById(id: Long): Flow<MyDataType> 

在我的例子中,我为 Roomandroid.arch. 使用 androidx 依赖关系,为 ViewModelLiveData 使用 [旧] 依赖关系,所以我收到了这条消息

解法: 使用所有 androidx 依赖项或使用 andrio.arch

的所有旧依赖项

如果有人在使用 Room 并使用 Kotlincoroutines 时在他们的 ViewModel 中实际需要 MutableLiveData<List<T>>,我就是这样解决的

在 Dao 中,我使用 suspend
获得 MutableList 在存储库中,我将上下文更改为 Dispatchers.IO 并使用 suspend
提取列表 在 ViewModel 中,我将 postValue 与 init 中的列表一起使用,语法如下

视图模型

    private val allItems = MutableLiveData<List<DocumentItem>>()
    init {
        viewModelScope.launch {
            allItems.postValue(repository.getAll())
        }
    }

存储库

    suspend fun getAll(): MutableList<DocumentItem> = withContext(Dispatchers.IO) {
        dao.getAll()
    }

道​​

    @Query("SELECT * FROM document_items ORDER BY id DESC")
    suspend fun getAll(): MutableList<DocumentItem>
@Query("select * from movie_action")
    suspend fun getMovieActionRoom() : LiveData<List<MoviesActionModel>>

只需删除挂起,在某些情况下错误就会消失。

在我的案例中,Room 不确定如何将 Cursor 转换为该方法的 return 类型,即 ArrayList 所以我稍微改变了一点,我将列表转换为 kotlin 的 MutableListOf。现在可以正常使用了。

在我将 Kotlin 版本从 1.5.21 改回 1.3.61 后,此错误消失了

我更新到最新版本Room后就没有了 - room_version = "2.4.0"

就我而言,升级版本有效。

上一个

api 'androidx.room:room-runtime:2.0.0'
annotationProcessor 'androidx.room:room-compiler:2.0.0'
api 'androidx.room:room-rxjava2:2.0.0'

现在

api 'androidx.room:room-runtime:+'
annotationProcessor 'androidx.room:room-compiler:+'
api 'androidx.room:room-rxjava2:+'

+ 表示最新版本,对我来说是 2.4.2