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

时间:2017-05-26 17:00:47

标签: android kotlin android-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。

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

9 个答案:

答案 0 :(得分:62)

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

答案 1 :(得分:6)

对于我来说,在项目中使用kotlin v.1.2.10及更高版本,它只适用于下一个方式:

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

在查询中命名“:userId ”,方法中的“ userId ”应该相同。

答案 2 :(得分:5)

如果您的 build.gradle 文件中未定义apply plugin: 'kotlin-kapt',则会出现此错误。如果你确实启用了kapt插件,编译器会将绑定参数与方法参数匹配。

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

答案 5 :(得分: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' }
    }
}

答案 6 :(得分:0)

此问题已在1.1.0-alpha3室修复。

有关此问题的更多信息,请访问:

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

答案 7 :(得分:0)

对我来说,这个问题在我在DAO界面中更改/添加方法时出现,我只用了Build > Clean Project后跟Build > Make Project就解决了。然后运行它。

答案 8 :(得分:0)

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

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