首页 文章

找不到字段的setter - 使用Kotlin和Room数据库

提问于
浏览
40

我正在与Room持久性库集成 . 我在Kotlin有一个数据类,如:

@Entity(tableName = "story")
data class Story (
        @PrimaryKey val id: Long,
        val by: String,
        val descendants: Int,
        val score: Int,
        val time: Long,
        val title: String,
        val type: String,
        val url: String
)

@Entity@PrimaryKey 注释适用于Room库 . 当我尝试构建时,它失败并出现错误:

Error:Cannot find setter for field.
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.

我也试过提供一个默认的构造函数:

@Entity(tableName = "story")
data class Story (
        @PrimaryKey val id: Long,
        val by: String,
        val descendants: Int,
        val score: Int,
        val time: Long,
        val title: String,
        val type: String,
        val url: String
) {
    constructor() : this(0, "", 0, 0, 0, "", "", "")
}

但这并不奏效 . 需要注意的是,如果我将这个Kotlin类转换为带有getter和setter的Java类,它就可以工作 . 任何帮助表示赞赏!

7 回答

  • 1

    在房间db库java代码生成中存在问题 .

    我正在使用可选字段 isFavorite . 它给了我同样的错误然后我将我的字段名称更改为 favorite 然后编译 .

    var isFavorite: Int? = 0, 之后改变工作正常 var favorite: Int? = 0, 谢谢

  • 1

    由于您的字段标有 val ,因此它们实际上是最终字段,并且没有setter字段 .

    尝试使用 var 切换 val . 您可能还需要初始化字段 .

    @Entity(tableName = "story")
    data class Story (
            @PrimaryKey var id: Long? = null,
            var by: String = "",
            var descendants: Int = 0,
            var score: Int = 0,
            var time: Long = 0L,
            var title: String = "",
            var type: String = "",
            var url: String = ""
    )
    
  • 14

    嘿,我不知道是否每个人都知道,但你不能有从 is 开始进入 Room 的专栏 . 例如,你不能有这样的

    @Entity(tableName = "user")
       data class User (
            @PrimaryKey var id: Long? = null,
            var userName: String = "",
            var isConnectedToFB: Boolean = false,
    )
    
  • 2

    在Java中有这个错误 . 您必须在构造函数中传递该字段并使用构造函数参数对其进行初始化,或者为其创建一个setter .

    例:

    public MyEntity(String name, ...) {
       this.name = name;
       ...
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
  • 2

    根据https://stackoverflow.com/a/46753804/2914140如果你有一个自动生成的主键,你应该这样写:

    @Entity(tableName = "story")
    data class Story (
            val by: String,
            val descendants: Int,
            val score: Int,
            val time: Long,
            val title: String,
            val type: String,
            val url: String
    )  {
        @PrimaryKey(autoGenerate = true)
        var id: Int = 0
    }
    

    请注意, @PrimaryKey 写在类体内,并包含修饰符 var .

    如果以后想要使用不同的参数更新数据库中的行,请使用以下行:

    val newStory = story.copy(by = "new author", title = "new title") // Cannot use "id" in object cloning
    newStory.id = story.id
    dao.update(newStory)
    
  • 98

    造成这种情况的另一个原因可能是该领域的命名 . 如果您使用任何预定义的关键字,您将得到相同的错误 . 例如,您无法将列命名为“is_active” .

    参考:http://www.sqlite.org/lang_keywords.html

  • 1

    这是一个错误,并在Room 2.1.0-alpha01 中修复

    https://developer.android.com/jetpack/docs/release-notes#october_8_2018

    Bug Fixes Room现在可以在数据类中正确使用Kotlin的主要构造函数,从而无需将字段声明为vars . B / 105769985

相关问题