Android Room:查询中的每个绑定变量都必须有一个匹配的方法

Posted

技术标签:

【中文标题】Android Room:查询中的每个绑定变量都必须有一个匹配的方法【英文标题】:Android Room : Each bind variable in the query must have a matching method 【发布时间】:2017-10-27 15:40:07 【问题描述】:

我正在使用带有 Kotlin 的 android 持久性库 Room

Dao 看起来像这样

@Dao
interface CountryDao 
    @Query("SELECT * FROM countries")
    fun loadAllCountried() : LiveData<List<CountryEntity>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAll(products: List<CountryEntity>)

    @Query("SELECT * FROM countries WHERE id = :countryId")
    fun loadCountry(countryId: Int): LiveData<CountryEntity>

    @Query("SELECT * FROM countries WHERE id = :countryId")
    fun loadCountrySync(countryId: Int): CountryEntity


这对我来说似乎不错,但我收到了这个错误

Error: Each bind variable in the query must have a matching method parameter. Cannot find method parameters for :countryId.

我可以看到参数被命名为countryId,那么可能是什么问题?

仅供参考: 这是CountryDao_Impl.java中生成的代码

@Override
public CountryEntity loadCountrySync(int arg0) 
  final String _sql = "SELECT * FROM countries WHERE id = ?";
  final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
  int _argIndex = 1;
  final Cursor _cursor = __db.query(_statement);
  try 
    final int _cursorIndexOfId = _cursor.getColumnIndexOrThrow("id");
    final int _cursorIndexOfPopulation = _cursor.getColumnIndexOrThrow("population");
    final CountryEntity _result;
   if(_cursor.moveToFirst()) 
     _result = new CountryEntity();
      final int _tmpId;
      _tmpId = _cursor.getInt(_cursorIndexOfId);
      _result.setId(_tmpId);
      final long _tmpPopulation;
      _tmpPopulation = _cursor.getLong(_cursorIndexOfPopulation);
      _result.setPopulation(_tmpPopulation);
     else 
      _result = null;
    
    return _result;
   finally 
    _cursor.close();
    _statement.release();
  

在这个方法中,我看到arg0 没有在该方法的任何地方使用。

编辑: 这似乎已在新插件中修复。这里有几个答案是正确的,但我不能接受每一个答案,对不起。

【问题讨论】:

这是一个错误youtrack.jetbrains.com/issue/KT-18048youtrack.jetbrains.com/issue/KT-17959issuetracker.google.com/issues/62125909 你是如何得到这个生成的代码的? 【参考方案1】:

Kotlin 没有正确保留参数的名称 - 这是https://youtrack.jetbrains.com/issue/KT-17959

您可以通过在@Query 语句中使用:arg0:arg1 等作为参数名称来解决此问题:

@Query("SELECT * FROM countries WHERE id = :arg0")
fun loadCountry(countryId: Int): LiveData<CountryEntity>

@Query("SELECT * FROM countries WHERE id = :arg0")
fun loadCountrySync(countryId: Int): CountryEntity

【讨论】:

我得到:查询中的每个绑定变量都必须有一个匹配的方法参数。找不到 :arg1、:arg0 的方法参数 请注意,截至 2019 年 4 月,在旧项目上对 android studio 进行了更新,将房间更新到 v1.1.1,我发现使用 arg0 实际上是问题所在,我不得不编辑我的 DOA 文件替换 arg0 以匹配函数参数名称。即 arg0 成为 countryId。【参考方案2】:

如果您没有在 build.gradle 文件中定义 apply plugin: 'kotlin-kapt',则会发生此错误。如果您确实启用了 kapt 插件,编译器将按预期将绑定参数与方法参数匹配。

【讨论】:

【参考方案3】:

对于我来说,在项目中使用 kotlin v.1.2.10 及更高版本,它只能通过下一种方式工作:

@Query("select * from user where pk = :userId")
fun findUserById(userId: Long): DBUser

查询中的名称“:userId”和方法中的“userId”应该相同。

【讨论】:

【参考方案4】:

对我来说,当我在DAO 接口或数据库Entity 类中更改/添加方法时出现了这个问题,我只用Build &gt; Clean Project 后跟Build &gt; Make Project 解决了这个问题。然后运行它。

【讨论】:

【参考方案5】:

现在可以使用 1.1.3-eap-85 和 kotlin-kapt 修复此问题。 Official tweet

【讨论】:

错误:找不到 org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.3-eap-85。【参考方案6】:

在 kotlin-gradle-plugin:1.1.3 中似乎已修复

【讨论】:

对我来说不是固定的。我必须使用 var0 我正在使用 1.1.61 版的 kotlin 等级插件,问题仍然存在。【参考方案7】:

正如Anton Kazakov 所说,此错误已在 kotlin 插件1.1.3-eap-85 中修复

但由于它尚未公开,您需要从他们的 privet 存储库而不是 jcenter 下载它

所以你需要在你的 build.gradle 中添加这一行

 maven  url 'https://dl.bintray.com/kotlin/kotlin-dev' 

例子

buildscript 
    ext 
        kotlin_version = '1.1.3-eap-85'
    

    repositories 
        google()
        jcenter()
        maven  url 'https://dl.bintray.com/kotlin/kotlin-dev' 
    
    dependencies 
        classpath 'com.android.tools.build:gradle:3.0.0-alpha7'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    


allprojects 
    repositories 
        google()
        jcenter()
        mavenCentral()
        maven  url 'https://dl.bintray.com/kotlin/kotlin-dev' 
    

【讨论】:

【参考方案8】:

这个问题已经在房间 1.1.0-alpha3 中得到修复。

有关此问题的更多信息在这里:

https://issuetracker.google.com/issues/68118746

【讨论】:

【参考方案9】:

以前的解决方案都不适合我。我在不同的模块中有@Dao 文件和@Database 文件。

我必须将所有文件(与 Room 相关)放在同一个模块中才能使错误消失。

【讨论】:

以上是关于Android Room:查询中的每个绑定变量都必须有一个匹配的方法的主要内容,如果未能解决你的问题,请参考以下文章

Android Room 数据库中的查询支持

在 Android 中将 MySql 查询转换为 SQL Room 查询 - kotlin

当用于模式匹配作为映射中的键时,变量是未绑定的

为啥此查询可以在 Android Studio 中的 App Inspection 的 Database Inspector 部分工作,但不能在 Room Query 中工作?

如何将 Not Null 表列迁移到 Android Room 数据库中的 Null

Android Room 的可选查询参数