当前位置:   article > 正文

android room可变参数,关于android:找不到字段的设置器-将Kotlin与Room数据库一起使用...

错误: cannot find setter for field

我正在与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类,它将起作用。 任何帮助表示赞赏!

在googles示例中的github.com/googlesamples/android-architecture-components/blob/中,不可变的属性可以正常工作。 有人可以分析原因吗? 可能是错误吗?

由于您的字段已标记为val,因此它们实际上是最终字段,没有设置者字段。

尝试用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 =""

)

嘿,我觉得这很奇怪,可以看看吗? stackoverflow.com/q/47323883/4620609

感谢您的指导,这个问题对我造成了大约2小时的死亡。....我使用了" private var",并且抛出错误,没有任何线索

答案是指不要使用Room,它会迫使您编写错误的代码,对吗?

请注意,数据类中的var使用会导致有效的不变性损失。

此解决方案对我有用,但对其他遇到相同问题的人也适用。我还必须删除我的私人可见性修改器。

无需使所有字段都可读/写。只需更改主键即可解决此问题

有时我们将实体设计为val不可变,而不是使用var。如果您更喜欢使用val而不是var,请在此处查看我的答案以获取此修复程序

嘿,我不知道每个人是否都知道,但是您不能拥有从is开始到Room的列。

例如你不能像这样

@Entity(tableName ="user")

data class User (

@PrimaryKey var id: Long? = null,

var userName: String ="",

var isConnectedToFB: Boolean = false,

)

我的男人,您节省了我数天的调试时间。

就我而言," is"前缀不适用于字段名称。但是" is"前缀适用于布尔类型字段。

无名英雄,谢谢。

它适用于java,但不适用于kotlin

@AlexAndro我在kotlin本身中给出了示例,您能解释一下什么不起作用吗?

@AJay我的意思是我同意你的观点,在kotlin中不能有这样的字段。 (表决)无论如何,在我注意到的java中是允许的。

@AlexAndro哦,好的

在Java中也会发生同样的事情。您不能使用" mIs___"或" is____"。它将导致相同的错误。匈牙利表示法不会挽救您。

在科特林工作

如果ColumnName不是以is开头的,则无关紧要。仅适用于重命名var

这是一个错误,已在房间2.1.0-alpha01中修复。

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

Bug Fixes

Room will now properly use Kotlin’s primary constructor in

data classes avoiding the need to declare the fields as vars.

b/105769985

我正在使用2.1.0-alpha03,但仍然收到此错误

与2.1.0-alpha04中的相同

在2.1.0-alpha06中得到此错误

房间数据库库Java代码生成中存在问题。

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

之前

var isFavorite: Int? = 0,

换工作后罚款

var favorite: Int? = 0,

谢谢

更改您的数据类型。我在数据库中有一个名为isFavourite的字段,我将字段类型更改为boolean,现在它对我有用。 @ColumnInfo(name =" is_favourite")var isFavourite:布尔值= false

这回答了我的问题,非常感谢!!!

根据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)

更新

我仍然不使用AndroidX,并且Room为" android.arch.persistence.room:runtime:1.1.1"。

您可以从Serializable扩展此类。但是,如果要从Parcelable扩展它,则会收到警告(在id变量上):Property would not be serialized inro a 'Parcel'. Add '@IgnoredOnParcel' annotation to remove this warning:

29fafbfcaf9b06b8a4887c2bcc0c649b.png

然后,将id从主体移动到构造函数。在Kotlin中,我使用@Parcelize创建Parcelable类:

@Parcelize

@Entity(tableName ="story")

data class Story (

@PrimaryKey(autoGenerate = true)

var id: Int = 0,

val by: String,

val descendants: Int,

val score: Int,

val time: Long,

val title: String,

val type: String,

val url: String

) : Parcelable

在Java中发生此错误。

在Java中,不能有以is或is_开头的列。

尝试重命名该列。

另一个解决方案:

您要么必须在构造函数中传递该字段,然后使用构造函数参数对其进行初始化,要么为其创建一个setter。

例:

public MyEntity(String name, ...) {

this.name = name;

...

}

public void setName(String name) {

this.name = name;

}

如果您希望实体具有val不变性,则可以。

您应该更新为AndroidX room当前版本。

在此处检查相关问题,将其标记为"无法修复"

现在他们已经发布了与2.0.0-beta01版本相关的修复程序

现在您可以将不可变的val与default value一起使用,例如:

@Entity("tbl_abc")

data class Abc(

@PrimaryKey

val id: Int = 0,

val isFavourite: Boolean = false

)

以前,以上代码段将引发错误Cannot find setter for field。更改为var是一个不错的解决方法,但是我更希望实体类不能从外部调用中更改

在花了几个小时在线研究为什么应该工作之后,如果有人在2019年遇到这个问题,这只是一个更新,但事实并非如此。

如果使用的是AndroidX版本(androidx.room:room-:2.*),则使用val可以按预期工作,但是使用旧的android.arch.persistence.room::1.1.1时则不能使用,并且似乎在此后一个版本中未发布版本2.*。

编辑:错别字

是的,AndroidX将替换支持库,因此Room在旧版android.arch.persistence.room上永远不会是2.0。

谢谢(你的)信息

别客气。我们必须尽快升级到AndroidX ...

val在我的情况下无法与Int和Long一起使用,即使使用androidx和最新的Room

造成此问题的另一个原因可能是该字段的命名。如果使用任何预定义的关键字,您将得到相同的错误。

例如,您不能将列命名为" is_active"。

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

现在,您可以使用is开头字段,但is旁边不能有数字,例如:is2FooSelected,必须将其重命名为isTwoFooSelected。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/259899
推荐阅读
相关标签
  

闽ICP备14008679号