J'essaie d'implémenter une bibliothèque persistante dans mon projet kotlin Android, mais je détecte cette erreur lors de la compilation:
erreur: Room ne peut pas choisir un constructeur car plusieurs constructeurs sont adapté. Essayez d'annoter les constructeurs indésirables avec @Ignore.
Code d'erreur:
@Entity
data class Site(
var name: String = "",
var url: String = "",
@PrimaryKey(autoGenerate = true) var id: Long = 0)
J'ai eu cette erreur parce que Kotlin génère apparemment plusieurs constructeurs Java pour un seul constructeur Kotlin avec des valeurs d'argument par défaut. Code de travail voir suivant:
@Entity
data class Site(
var name: String,
var url: String,
@PrimaryKey(autoGenerate = true) var id: Long)
Aucune des solutions ci-dessus n'est bonne, car elles fonctionnent mais peuvent provoquer des erreurs.
La classe Data de Kotlin génère plusieurs méthodes à l'aide du constructeur par défaut. Cela signifie que equals () , hashCode () , toString () , composantN () (fonctions) et copy () sont générés à l'aide du attributs que vous attribuez à votre constructeur.
En utilisant les solutions ci-dessus comme
@Entity data class Site(@PrimaryKey(autoGenerate = true) var id: Long) {
@Ignore constructor() : this(0)
var name: String = ""
var url: String = ""
}
génère toutes les méthodes énumérées ci-dessus uniquement pour id. L'utilisation de l'égal conduit à une qualité indésirable, identique à toString (). Pour résoudre ce problème, vous devez avoir tous les attributs que vous souhaitez traiter dans le constructeur et ajouter un second constructeur en utilisant ignore comme
@Entity data class Site(
@NonNull @PrimaryKey(autoGenerate = true) var id: Long,
var name: String = "",
var url: String = "") {
@Ignore constructor(id = 0, name = ", url = "") : this()
}
N'oubliez pas que vous utilisez généralement des classes de données pour utiliser des méthodes telles que toString et copy. Seule cette solution permet d'éviter les bogues indésirables lors de l'exécution.
Cela a fonctionné pour moi:
@Entity
data class Site(
@PrimaryKey(autoGenerate = true) var id: Long = 0),
var name: String = "",
var url: String = "",
@Ignore var ignored: String? = null
)
ça marche pour moi
@Entity
data class TaskDetail @Ignore constructor(
@PrimaryKey(autoGenerate = true)
var id:Long = 0,
var taskId:Long = 0,
var content:String = "")
{
constructor():this(id = 0)
}
J'utilise @ Ignore pour interdire l'avertissement ROOM
Il y a plusieurs bons constructeurs et Room choisira le constructeur sans argument. Vous pouvez utiliser l'annotation @Ignore pour éliminer les constructeurs indésirables.
Et ajoutez un constructeur par défaut pour ROOM.
Ici, vous changez votre base de données d'applications version
et redémarrez le programme une fois, cela fonctionnera:
@Database(entities = arrayOf(Site::class), version = 123) abstract class YourAppDatabase : RoomDatabase() {
abstract fun yourDao(): YourDao
}
et vous pouvez aussi essayer ceci data class
:
@Entity
data class Site(@PrimaryKey(autoGenerate = true) var id: Long) {
@Ignore constructor() : this(0)
var name: String = "",
var url: String = "",
}
et la dernière instruction: votre clé primaire id
devrait être incrémentée manuellement .
J'espère que cela fonctionne pour vous. :)
Testez pour montrer que les réponses ci-dessus ne sont pas valides.
data class TestModel(var id: Int = 0) {
constructor() : this(0)
var name: String = "defaultname"
var testData: String = "defaulttestData"
}
val testModel = TestModel(5)
testModel.name = "test"
val testModel2 = TestModel(5)
testModel2.testData = "testdata"
testModel2.name = "test"
info { "Test with name set: $testModel" }
info { "Testdata equals Testdata2 ${testModel.equals(testModel2)}" }
renvoie Test avec le nom défini: TestModel (id = 5) et Testdata est égal à Testdata2 true
Essayez de changer le type de données variable de val en var:
AVANT :
@Entity
data class Product(
@PrimaryKey
val id: String = "",
val name: String = ""
)
APRÈS :
@Entity
data class Product(
@PrimaryKey
var id: String = "",
var name: String = ""
)
Je laisse juste ma réponse au cas où cela aiderait quelqu'un. J'ai rencontré le même problème, aucune des réponses ci-dessus n'a fonctionné. La seule chose qui a fonctionné a été de passer d'un data class
à un class
. J'invite n'importe qui à essayer le même code et à expliquer pourquoi il a fait l'affaire:
Avant
@Entity
data class ImgurGalleryPost (
@NotNull @PrimaryKey
var id: String,
var title: String?,
var description: String?,
var datetime: Int?,
var cover: String?,
var coverWidth: Int?,
var coverHeight: Int?,
var accountUrl: String?,
var accountId: Int?,
var privacy: String?,
var layout: String?,
var views: Int?,
var link: String?,
var ups: Int?,
var downs: Int?,
var points: Int?,
var score: Int?,
var isAlbum: Boolean?,
var vote: Boolean?,
var favorite: Boolean?,
var nsfw: Boolean?,
var section: String?,
var commentCount: Int?,
var favoriteCount: Int?,
var topic: String?,
var topicId: Int?,
var imagesCount: Int?,
var inGallery: Boolean?,
var isAd: Boolean?,
@NotNull @Ignore
var tags: List<ImgurGalleryTag>,
var inMostViral: Boolean?,
@NotNull @Ignore
var images: List<ImgurGalleryImage>
)
Après
@Entity
class ImgurGalleryPost (
@NotNull @PrimaryKey
var id: String,
var title: String?,
var description: String?,
var datetime: Int?,
var cover: String?,
var coverWidth: Int?,
var coverHeight: Int?,
var accountUrl: String?,
var accountId: Int?,
var privacy: String?,
var layout: String?,
var views: Int?,
var link: String?,
var ups: Int?,
var downs: Int?,
var points: Int?,
var score: Int?,
var isAlbum: Boolean?,
var vote: Boolean?,
var favorite: Boolean?,
var nsfw: Boolean?,
var section: String?,
var commentCount: Int?,
var favoriteCount: Int?,
var topic: String?,
var topicId: Int?,
var imagesCount: Int?,
var inGallery: Boolean?,
var isAd: Boolean?,
@NotNull @Ignore
var tags: List<ImgurGalleryTag>,
var inMostViral: Boolean?,
@NotNull @Ignore
var images:
List<ImgurGalleryImage>
)
C’est vraiment bizarre, mais je doute que ce soit un problème de cache d’Android Studio, car le fait de revenir au data class
entraîne la réapparition de l’erreur. Cela semble être un problème avec les champs de collection. J'ai vérifié le constructeur dans la classe générée et ça avait l'air bien, je ne sais pas pourquoi la construction échouait alors même que le constructeur était généré correctement:
public ImgurGalleryPost(@org.jetbrains.annotations.NotNull()
Java.lang.String id, @org.jetbrains.annotations.Nullable()
Java.lang.String title, @org.jetbrains.annotations.Nullable()
Java.lang.String description, @org.jetbrains.annotations.Nullable()
Java.lang.Integer datetime, @org.jetbrains.annotations.Nullable()
Java.lang.String cover, @org.jetbrains.annotations.Nullable()
Java.lang.Integer coverWidth, @org.jetbrains.annotations.Nullable()
Java.lang.Integer coverHeight, @org.jetbrains.annotations.Nullable()
Java.lang.String accountUrl, @org.jetbrains.annotations.Nullable()
Java.lang.Integer accountId, @org.jetbrains.annotations.Nullable()
Java.lang.String privacy, @org.jetbrains.annotations.Nullable()
Java.lang.String layout, @org.jetbrains.annotations.Nullable()
Java.lang.Integer views, @org.jetbrains.annotations.Nullable()
Java.lang.String link, @org.jetbrains.annotations.Nullable()
Java.lang.Integer ups, @org.jetbrains.annotations.Nullable()
Java.lang.Integer downs, @org.jetbrains.annotations.Nullable()
Java.lang.Integer points, @org.jetbrains.annotations.Nullable()
Java.lang.Integer score, @org.jetbrains.annotations.Nullable()
Java.lang.Boolean isAlbum, @org.jetbrains.annotations.Nullable()
Java.lang.Boolean vote, @org.jetbrains.annotations.Nullable()
Java.lang.Boolean favorite, @org.jetbrains.annotations.Nullable()
Java.lang.Boolean nsfw, @org.jetbrains.annotations.Nullable()
Java.lang.String section, @org.jetbrains.annotations.Nullable()
Java.lang.Integer commentCount, @org.jetbrains.annotations.Nullable()
Java.lang.Integer favoriteCount, @org.jetbrains.annotations.Nullable()
Java.lang.String topic, @org.jetbrains.annotations.Nullable()
Java.lang.Integer topicId, @org.jetbrains.annotations.Nullable()
Java.lang.Integer imagesCount, @org.jetbrains.annotations.Nullable()
Java.lang.Boolean inGallery, @org.jetbrains.annotations.Nullable()
Java.lang.Boolean isAd, @org.jetbrains.annotations.NotNull()
Java.util.List<com.kimboo.core.model.ImgurGalleryTag> tags, @org.jetbrains.annotations.Nullable()
Java.lang.Boolean inMostViral, @org.jetbrains.annotations.NotNull()
Java.util.List<com.kimboo.core.model.ImgurGalleryImage> images) {
super();
}
Si quelqu'un peut trouver un moyen de résoudre ce problème sans passer de data class
à class
, n'hésitez pas à commenter ci-dessous.
L'erreur est provoquée par les variables initialement définies dans le constructeur. Si vous n'avez qu'un seul constructeur, remplacez votre code par ceci.
@Entity
data class Site(
val name: String,
val url: String,
@PrimaryKey(autoGenerate = true) val id: Long)
Si vous avez aussi besoin d'un constructeur vide, alors vous devriez faire comme ceci
@Entity
data class Site() {
constructor(name: String, url: String): this() {
this.name = name
this.url = url
}
var name: String = "",
var url: String = "",
@PrimaryKey(autoGenerate = true) var id: Long = 0
}