Android Room : Each bind variable in the query must have a matching method

Viewed 10735

I am using the android persistence library Room with Kotlin.

The Dao looks like this

@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

}

It seems good to me but I am getting this error

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

I can see the parameter is named as countryId, so what may be the issue?

FYI: Here is the generated code in 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();
  }
}

In this method I see arg0 is not being used anywhere in the method.

EDIT: This seems to be fixed in the new plugins. Several of the answers here are correct, but I can't accept every answer, Sorry.

9 Answers

This error occurs if you do not have apply plugin: 'kotlin-kapt' defined in your build.gradle file. If you do enable the kapt plugin, the compiler will match the binding parameter with the method arguments as expected.

With kotlin v.1.2.10 and higher in the project for me it works only by next way:

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

names ":userId" in the query and "userId" in the method should be the same.

For me, this issue appeared when I change/add methods in either the DAO interface or database Entity classes, and I solved it by just Build > Clean Project followed by Build > Make Project. then run it.

None of the previous solutions worked for me. I had the @Dao files and the @Database file in different modules.

I had to put all the files (related to Room) in the same module for the error to disappear.

Related