113 votes

Impossible de trouver un paramètre pour le champ - utilisation de la base de données Kotlin with Room

Je suis à l'intégration avec la Salle de la persistance de la bibliothèque. J'ai une classe de données dans Kotlin comme:

@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
)

L' @Entity et @PrimaryKey annotations sont pour la Salle de la bibliothèque. 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 qu'il fonctionne si je convertir ce Kotlin classe dans une classe Java avec des getters et setters. Toute aide est appréciée!

230voto

Jan Vladimir Mostert Points 1133

Étant donné que vos champs sont marqués avec val , ils sont effectivement finaux et n'ont pas de champs de définition.

Essayez de changer les val avec var . Vous devrez peut-être également 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 = ""
)
 

59voto

AJay Points 26

Hé, je ne sais pas si tout le monde sait ou non, mais vous ne pouvez pas avoir une colonne qui commence à is en Room . Par exemple, vous ne pouvez pas avoir comme ça

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

10voto

Qamar Points 2182

Il y a un problème dans la génération de code Java de la bibliothèque de la base de données room.

J'utilisais le champ facultatif isFavorite . Cela me donne la même erreur, puis je change le nom de mon champ en favorite puis compilé.

avant var isFavorite: Int? = 0, après avoir changé l'amende de travail var favorite: Int? = 0, Merci

8voto

CoolMind Points 11

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 à l'intérieur du corps de classe et contient le modificateur var.

Si plus tard vous souhaitez mettre à jour une ligne dans une base de données avec des paramètres différents, l'utilisation de 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)

Mise à JOUR

Je n'ai pas encore utiliser AndroidX, et la Chambre est android.arch.la persistance.chambre:runtime:1.1.1'.

Vous pouvez étendre cette classe d' Serializable. Mais si vous voulez l'étendre à partir d' Parcelable, vous obtiendrez un avertissement (plus de id variable): Property would not be serialized inro a 'Parcel'. Add '@IgnoredOnParcel' annotation to remove this warning:

enter image description here

Puis, j'ai déménagé un id du corps du constructeur. Dans Kotlin-je utiliser @Parcelize créer Parcelable classes:

@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

8voto

40-Love Points 1333

Eu cette erreur en Java. Vous devez soit passer le champ dans le constructeur et l'initialiser avec l'argument constructeur, soit créer un outil de définition pour celui-ci.

Exemple:

 public MyEntity(String name, ...) {
   this.name = name;
   ...
}

public void setName(String name) {
    this.name = name;
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X