赞
踩
我正在与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:
然后,将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。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。