Комната Android: каждая переменная связывания в запросе должна иметь соответствующий метод

Я использую android persistence library Room с kotlin.

Дао выглядит так

@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 , так что может быть проблемой?

FYI: Вот код генерации в 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 не используется нигде в методе.

EDIT: похоже, это исправлено в новых плагинах. Несколько ответов правильные, поэтому не можете принять каждый ответ, Извините.

Котлин не сохраняет имена аргументов правильно – это 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 

С kotlin v.1.2.10 в проекте для меня это работает только следующим образом:

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

имена : userId в запросе и userId в методе должны быть одинаковыми.

Кажется исправленным в kotlin-gradle-plugin: 1.1.3

Эта проблема теперь может быть исправлена ​​с использованием 1.1.3-eap-85 и kotlin-kapt. Официальный твит

Как сказал Антон Казаков, эта ошибка исправлена ​​в плагине kotlin 1.1.3-eap-85

но поскольку он еще не является общедоступным, вам необходимо загрузить его из своего приватного хранилища, а не 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' } } }