35

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

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没有在该方法的任何地方使用。

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

4

9 回答 9

66

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

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

@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
于 2017-05-27T03:10:06.257 回答
10

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

于 2018-02-07T04:40:56.897 回答
8

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

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

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

于 2018-01-13T17:31:49.273 回答
2

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

于 2020-07-23T23:14:43.230 回答
1

现在可以使用 1.1.3-eap-85 和 kotlin-kapt 修复此问题。 官方推文

于 2017-06-29T12:05:54.213 回答
0

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

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

于 2021-08-04T10:32:34.923 回答
0

此问题已在房间 1.1.0-alpha3 中修复。

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

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

于 2018-03-09T04:08:48.057 回答
0

正如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' }
    }
}
于 2017-07-22T23:08:07.527 回答
0

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

于 2017-06-27T21:28:14.597 回答