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

41

我正在使用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: 在查询中每个绑定变量必须有一个匹配的方法参数。找不到: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没有在函数中被使用。

编辑: 在新的插件中已经修复了这个问题。这里的几个答案都是正确的,但我不能接受每一个答案,请见谅。


2
这是一个错误 https://youtrack.jetbrains.com/issue/KT-18048https://youtrack.jetbrains.com/issue/KT-17959https://issuetracker.google.com/issues/62125909 - Anton Holovin
你是如何获得这段生成的代码的? - Sourav Kannantha B
10个回答

67

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 的方法参数。 - Mladen Rakonjac
1
请注意,截至2019年4月,在旧项目上更新Android Studio并将Room更新到v1.1.1后,我发现使用arg0实际上是问题所在,我不得不编辑我的DOA文件以将arg0替换为匹配的函数参数名称。即arg0变成了countryId。 - Emile

13

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


8

对于项目中使用kotlin v.1.2.10及更高版本,仅有以下方式可以正常工作:

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

查询中的参数 ":userId" 和方法中的参数 "userId" 应该相同。


6

对我来说,当我更改/添加DAO接口或数据库Entity类的方法时,出现了这个问题,我通过简单地执行Build > Clean Project,然后执行Build > Make Project来解决它。然后运行它。


1

之前的解决方案对我都没用。我的@Dao文件和@Database文件在不同的模块中。

我必须把所有与Room相关的文件放在同一个模块中,才能消除错误。


这是我尝试按照此处描述的方式导出数据库模式时唯一有效的解决方案: https://dev59.com/6FcP5IYBdhLWcg3wf58G#48674264 在这个 Android 开发者培训应用程序中: https://github.com/google-developer-training/android-basics-kotlin-bus-schedule-app - CyclingSir

1
现在可以使用1.1.3-eap-85和kotlin-kapt来解决此问题。 官方推文


错误:找不到org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.3-eap-85。 - Mladen Rakonjac

1
我在将kotlinVersion更新为1.9.0kotlinCompilerExtensionVersion更新为1.5.0后遇到了同样的问题。 我没有深入研究,但经过一些调试后,我决定尝试一下KSP(用于Kotlin的新注解处理器),结果解决了我的问题! 从官方文档中,我还了解到:

Kapt现在处于维护模式,我们建议尽可能迁移到KSP。在大多数情况下,这个迁移只需要对项目的构建配置进行一些更改。

如果你在2023年面临同样的问题,转换到KSP可能会有所帮助。

0

正如Anton Kazakov所说,这个bug已经在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' }
    }
}

0

0

看起来在 kotlin-gradle-plugin:1.1.3 中已经修复了


4
对我来说还没有固定的。我必须使用var0。 - Alexander N.
1
我正在使用Kotlin Gradle插件的1.1.61版本,但问题仍然存在。 - Willi Mentzel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接