libreria - sqlite room android
No se puede encontrar el configurador para el campo: usar Kotlin con la base de datos de Room (9)
Como sus campos están marcados con
val
, son efectivamente finales y no tienen campos de establecimiento.
Intente cambiar el
val
con
var
.
Es posible que también deba inicializar los campos.
@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 = ""
)
Me estoy integrando con la biblioteca de persistencia de la sala. Tengo una clase de datos en Kotlin como:
@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
)
Las anotaciones
@Entity
y
@PrimaryKey
son para la biblioteca Room.
Cuando intento compilar, falla con error:
Error:Cannot find setter for field.
Error:Execution failed for task '':app:compileDebugJavaWithJavac''.
> Compilation failed; see the compiler error output for details.
También intenté proporcionar un constructor predeterminado:
@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, "", "", "")
}
Pero esto no funciona tan bien. Una cosa a tener en cuenta es que funciona si convierto esta clase de Kotlin en una clase de Java con getters y setters. Cualquier ayuda es apreciada!
De acuerdo con https://.com/a/46753804/2914140 si tiene una clave primaria autogenerada, debe escribir así:
@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
}
Tenga en cuenta que
@PrimaryKey
está escrito dentro del cuerpo de la clase y contiene el modificador
var
.
Si luego desea actualizar una fila en una base de datos con diferentes parámetros, use estas líneas:
val newStory = story.copy(by = "new author", title = "new title") // Cannot use "id" in object cloning
newStory.id = story.id
dao.update(newStory)
ACTUALIZAR
Todavía no uso AndroidX, y Room es ''android.arch.persistence.room:runtime:1.1.1''.
Puede ampliar esta clase desde
Serializable
.
Pero si desea extenderlo desde
Parcelable
, recibirá una advertencia (sobre la variable
id
): la
Property would not be serialized inro a ''Parcel''. Add ''@IgnoredOnParcel'' annotation to remove this warning
Property would not be serialized inro a ''Parcel''. Add ''@IgnoredOnParcel'' annotation to remove this warning
:
Luego moví una
id
del cuerpo al constructor.
En Kotlin uso
@Parcelize
para crear clases
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
Esto es un error y se solucionó en la habitación
2.1.0-alpha01
https://developer.android.com/jetpack/docs/release-notes#october_8_2018
Corrección de errores
- Room ahora usará correctamente el constructor primario de Kotlin en las clases de datos, evitando la necesidad de declarar los campos como vars. b/105769985
Hay un problema en la generación de código Java de la biblioteca db de la sala.
Estaba usando el campo opcional
isFavorite
.
Me da el mismo error, luego cambio el nombre de mi campo a
favorite
luego lo compilo.
antes de
var isFavorite: Int? = 0,
var isFavorite: Int? = 0,
después de cambiar el trabajo bien
var favorite: Int? = 0,
var favorite: Int? = 0,
gracias
Otra causa de esto puede ser la denominación del campo. Si utiliza alguna de las palabras clave predefinidas, obtendrá el mismo error. Por ejemplo, no puede nombrar su columna "is_active".
Referencia: http://www.sqlite.org/lang_keywords.html
Oye, no sé si todos lo saben o no, pero no puedes tener una columna que comience desde la
Room
.
Por ejemplo, no puedes tener así
@Entity(tableName = "user")
data class User (
@PrimaryKey var id: Long? = null,
var userName: String = "",
var isConnectedToFB: Boolean = false,
)
Si desea que la inmutabilidad
val
esté disponible para su entidad, es posible.
- Debes actualizar a la versión actual de AndroidX room.
- Compruebe el problema relacionado aquí , está marcado como No soluciona
- Ahora han lanzado una solución relacionada con el problema con la versión 2.0.0-beta01
-
Ahora puede usar
val
inmutable condefault value
por ejemplo:
@Entity("tbl_abc")
data class Abc(
@PrimaryKey
val id: Int = 0,
val isFavourite: Boolean = false
)
Anteriormente, el fragmento anterior arrojará un error de
Cannot find setter for field
.
Cambiar a
var
es una gran solución, pero prefiero que la clase de entidad sea inmutable desde una invocación externa
Solo una actualización si alguien se encuentra con este hilo en 2019, después de pasar horas investigando por qué esto debería funcionar, pero no funciona.
El uso de
val
funciona como se espera si está utilizando la versión de
androidx.room:room-<any>:2.*
(
androidx.room:room-<any>:2.*
) pero no lo hace cuando usa el viejo
android.arch.persistence.room:<any>:1.1.1
:
androidx.room:room-<any>:2.*
:
androidx.room:room-<any>:2.*
android.arch.persistence.room:<any>:1.1.1
y parece que la versión
2.*
no se lanzó en este último repositorio.
Editar: errores tipográficos
Tenía este error en Java.
No puede tener una columna que comience con
is
o
is_
en Java.
Intente renombrar la columna.
Otra solución:
Debe pasar el campo en el constructor e inicializarlo con el argumento del constructor, o crear un setter para él.
Ejemplo:
public MyEntity(String name, ...) {
this.name = name;
...
}
public void setName(String name) {
this.name = name;
}