Impossible de trouver setter pour field-en utilisant Kotlin avec la base de données des chambres
Je m'intègre à la bibliothèque Room persistence. J'ai une classe de données dans Kotlin de la forme:
@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
et @PrimaryKey
les annotations sont pour la bibliothèque de la salle. Quand j'essaie de compiler, il échoue avec l'erreur:
Error:Cannot find setter for field.
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.
j'ai aussi essayé de fournir un constructeur par défaut:
@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, "", "", "")
}
Mais cela ne fonctionne pas ainsi. Une chose à noter est que cela fonctionne si je convertis cette classe Kotlin en une classe Java avec getters et setters. Toute aide est la apprécié!
6 réponses
puisque vos champs sont marqués par val
, elles sont effectivement finales et n'ont pas de champs setter.
essayez de changer le val
var
.
Vous pouvez également avoir besoin d'initialiser les champs.
@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 = ""
)
Hey je ne sais pas si tout le monde le sais ou pas, mais vous ne pouvez pas avoir la colonne qui commence par is
en Room
.
Par exemple, vous ne pouvez pas avoir comme ceci
@Entity(tableName = "user")
data class User (
@PrimaryKey var id: Long? = null,
var userName: String = "",
var isConnectedToFB: Boolean = false,
)
avait cette erreur en Java. Vous devez soit passer le champ dans le constructeur et l'initialiser avec l'argument constructeur, ou créer un setter pour lui.
Exemple:
public MyEntity(String name, ...) {
this.name = name;
...
}
public void setName(String name) {
this.name = name;
}
Selon https://stackoverflow.com/a/46753804/2914140 si vous avez une clé primaire générée automatiquement, vous devez écrire:
@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
}
Notez que @PrimaryKey
est écrit dans le corps de la classe et contient le modificateur var
.
si vous voulez plus tard mettre à jour une ligne dans une base de données avec des paramètres différents, utilisez ces lignes:
val newStory = story.copy(by = "new author", title = "new title") // Cannot use "id" in object cloning
newStory.id = story.id
dao.update(newStory)
une autre cause de cela peut être le nom du champ. Si vous utilisez l'un des mots clés prédéfinis, vous obtiendrez la même erreur. Par exemple, vous ne pouvez pas nommer votre colonne "is_active".
Référence: http://www.sqlite.org/lang_keywords.html
il y a un problème dans la génération de code java de la bibliothèque DB.
j'étais champ facultatif isFavorite
et compiler l'heure même erreur puis je change mon nom de champ en favorite
ensuite compilé.
avant de
var isFavorite: Int? = 0,
après le changement de l'amende de travail
var favorite: Int? = 0,
Merci