【问题标题】:Room "Not sure how to convert a Cursor to this method's return type": which method?Room “不确定如何将 Cursor 转换为此方法的返回类型”:哪种方法?
【发布时间】:2018-03-08 19:53:44
【问题描述】:
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 我遇到了这个错误,我想知道是什么方法导致的。

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

我可以发布DAOs 的整个课程,但是我要求一种方法来知道哪个方法失败了。我尝试了Run with --stacktraceRun with --info--debug option,但这些都没有显示任何有价值的信息。

我添加的方法是@QueryUPDATE,返回类型为Int,正如documentation中所建议的那样

UPDATE 或 DELETE 查询可以返回 void 或 int。如果是 int,则 value 是受此查询影响的行数。

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

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

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

【问题讨论】:

  • gradle 控制台的完整错误信息是什么?
  • @pskink 将完整的错误消息添加到问题中
  • 这是我编译得很好的方法:@Query("SELECT * FROM user") LiveData<List<User>> loadUsers(); 当我将List 更改为Vector 例如我得到:UserDao.java:19: error: Not sure how to convert a Cursor to this method's return type LiveData<Vector<User>> loadUsers();Gradle 控制台 android studio的窗口-注意它显示UserDao.java:19这是一个行位置,它还打印错误的方法,更多developer.android.com/studio/run/index.html#gradle-console
  • 我是从 Kotlin 构建的,也许这就是为什么我没有接听电话?
  • 我今天遇到了同样的问题(返回类型是 rxjava2 Observable)。错误消息不包含有关问题所在位置的任何信息。我希望谷歌将使错误消息更具信息性。至少它应该打印一个方法名称或预期的返回类型......

标签: android dao android-room kapt android-architecture-components


【解决方案1】:

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

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

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

【讨论】:

  • 对于Co-routines 的支持,我添加了implementation "androidx.room:room-coroutines:${versions.room}" 依赖,但是Build failed 说`ERROR: Failed to resolve: androidx.room:room-coroutines:2.2.1'.
  • 这是我的问题。返回 LiveData 时,不应使用挂起函数,因为它们不兼容(并且不需要)。
  • @iCantC 你可以只导入implementation "androidx.room:room-ktx:$room_version",这是关于如何为 Room 集成协程支持的最新变体。另见官方文档:developer.android.com/jetpack/androidx/releases/room
  • 很高兴知道,是的,这也是我的问题的原因。谢谢。
  • 仅供参考,自 Version 2.1.0-alpha05 起,“room-coroutines”已重命名为“room-ktx”。但是,我的项目中已经有了这个,它没有修复错误。根据这个答案删除 suspend 确实为我解决了错误。
【解决方案2】:

我花了一整天的时间在这个问题上。解决方案非常简单。我之前用过这样的东西

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

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

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

基于这个问题的答案和 cmets,我认为房间仅支持 List 和 LiveData,因为我也尝试过 MutableLiveData 和仅 ArrayList。没有一种组合奏效。

希望这将帮助某人几个小时。

【讨论】:

  • 我收到同样的错误:@Query("SELECT * FROM category_table") LiveData> getCategories();
  • 那是因为 Room 会有自己的 List 类型,而不是 ArrayList。您应该始终引用 List 作为您的类型,唯一一次直接使用 ArrayList 是在构造期间。
  • 就我而言,我使用的是挂起。
  • 如果你使用 LiveData 或 Flow 并挂起,你会得到同样的错误
  • 天啊,暂停是我的问题,谢谢@jorg
【解决方案3】:

对于任何登陆这里的人,使用coroutine Flow 作为返回类型,如果您不小心使函数挂起,您将收到此错误。既然是返回流,就不用暂停了。

所以不要这样:

@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> 

【讨论】:

  • 你拯救了我的一天!
  • @gMale 因为它不再是一个暂停的功能,我应该在收集Flow 时调用.flowOn(Dispatchers.IO) 吗?
【解决方案4】:

是的,根据您在 cmets 中提到的内容,您不能将返回类型从 List 更改为 Dao 内的任何其他内容。我假设 Room 不知道如何处理其他返回类型。获取List 并将其转换/转换为Dao 之外的所需类型。

【讨论】:

    【解决方案5】:

    在我的情况下,当我在 Dao 类中使用 LiveData&lt;ArrayList&lt;Example Class&gt;&gt; 从 Room 获取所有东西时,我遇到了这个问题,当我将 ArrayList 更改为 List 时,我解决了这个问题。

    示例(Kotlin):

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

    【讨论】:

    • 你在这个例子中使用了哪些版本的房间? LiveData 不是问题吧?
    • 我使用的是“1.1.1”版本。就我而言,我以这种方式修复了!
    • 我明白了。谢谢!!
    • 如果您希望能够修改您的 LiveData&lt;List&lt;Example&gt;&gt; 而不会出现此错误,请将其更改为 LiveData&lt;MutableList&lt;Example&gt;&gt;
    • 那是因为 Room 正在返回 List 的不同实现,但您正试图将其强制转换为 ArrayList。
    【解决方案6】:

    我更新到最新版本 Room - room_version = "2.4.0" 后它消失了

    【讨论】:

      【解决方案7】:
      @Query("select * from movie_action")
          suspend fun getMovieActionRoom() : LiveData<List<MoviesActionModel>>
      

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

      【讨论】:

        【解决方案8】:

        我的应用有不同的用例。

        所以,我正在尝试返回实际的 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 文件后,我发现Cursorsuspend 关键字的关系不正常。

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

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

        瞧,它有效。

        【讨论】:

          【解决方案9】:

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

          【讨论】:

          • 这很有帮助!
          【解决方案10】:

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

          解决方案: 要么使用所有 androidx 依赖项,要么使用 andrio.arch 的所有旧依赖项

          【讨论】:

            【解决方案11】:

            如果有人在使用Room 并使用Kotlincoroutines 时在他们的ViewModel 中确实需要MutableLiveData&lt;List&lt;T&gt;&gt;,这就是我解决它的方法

            在 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>
            

            【讨论】:

              【解决方案12】:

              对于我的情况,在得到“不确定如何将游标转换为此方法的返回类型”之后:

              删除“build”并重新build,错误消失。

              【讨论】:

              • 大声笑,修复了一些没有任何意义的错误!谢谢!
              【解决方案13】:

              在 build.gradle 的 defaultConfig 中添加以下代码

              javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true
              

              【讨论】:

              • 想解释一下原因吗?
              • 我们希望对此作出解释,因为此解决方案不起作用。
              【解决方案14】:

              对我来说,我在查询中使用了错误的返回类型。

              【讨论】:

                【解决方案15】:

                确保您没有将挂起与 LiveData 一起用作返回类型:

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

                【讨论】:

                  【解决方案16】:
                   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,你也会得到这个错误。

                  【讨论】:

                    【解决方案17】:

                    修改你的 Dao,使用 Flowable 代替 observable 并添加以下依赖(room with rxjava support)

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

                    Dao 返回 flowable:

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

                    【讨论】:

                      【解决方案18】:

                      对我来说,它是从 MutableLiveData 更改为 LiveData 作为 get 方法的返回类型。

                      【讨论】:

                        【解决方案19】:

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

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

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

                        【讨论】:

                          【解决方案20】:

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

                          【讨论】:

                            【解决方案21】:

                            确定是否有

                            查询有问题:[SQLITE_ERROR] SQL 错误或缺失 数据库(没有这样的表:METRO)


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

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

                            【讨论】:

                              【解决方案22】:

                              就我而言,Room 不知道如何将 Cursor 转换为此方法的返回类型,即 ArrayList 所以我改变了一点,我将列表转换为 kotlin 的MutableListOf。现在它工作正常。

                              【讨论】:

                                【解决方案23】:

                                在我的情况下,升级版本有效。

                                上一个

                                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

                                【讨论】:

                                  【解决方案24】:

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

                                  【讨论】:

                                  • 这并不能解决问题。需要确定问题的原因。降级 Kotlin 版本永远不是解决方案。
                                  猜你喜欢
                                  • 2019-12-12
                                  • 1970-01-01
                                  • 2019-04-23
                                  • 2020-12-01
                                  • 2019-08-11
                                  • 2021-12-30
                                  • 2021-06-20
                                  • 2019-12-03
                                  相关资源
                                  最近更新 更多