Комната не может выбрать конструктор, так как несколько конструкторов являются подходящей ошибкой

Я пытаюсь реализовать постоянную библиотеку в моем проекте Android Kotlin, но поймать эту ошибку во время компиляции:

ошибка: Комната не может выбрать конструктор, так как подходит несколько конструкторов. Попробуйте аннотировать нежелательные конструкторы с помощью @Ignore.

Код ошибки:

@Entity
data class Site(
        var name: String = "",
        var url: String = "",
        @PrimaryKey(autoGenerate = true) var id: Long = 0)

10 ответов

Решение

У меня была эта ошибка, потому что Kotlin, очевидно, генерирует несколько Java-конструкторов для одного конструктора Kotlin со значениями аргументов по умолчанию. Рабочий код смотрите далее:

@Entity
data class Site(
        var name: String,
        var url: String,
        @PrimaryKey(autoGenerate = true) var id: Long)

Ни одно из вышеперечисленных решений не подходит, так как они работают, но могут привести к ошибкам.

Класс данных Kotlin генерирует несколько методов, используя конструктор по умолчанию. Это означает, что функции equals (), hashCode (), toString (), componentN () и copy() генерируются с использованием атрибутов, которые вы присваиваете своему конструктору.

Используя вышеуказанные решения, такие как

@Entity data class Site(@PrimaryKey(autoGenerate = true) var id: Long) {
    @Ignore constructor() : this(0)
    var name: String = ""
    var url: String = ""
} 

генерирует все вышеперечисленные методы только для id. Использование equals приводит к нежелательному качеству, так же как toString(). Чтобы решить эту проблему, вам нужно иметь все атрибуты, которые вы хотите обработать внутри конструктора и добавить второй конструктор, используя ignore like

@Entity data class Site(
    @NonNull @PrimaryKey(autoGenerate = true) var id: Long,
    var name: String = "",
    var url: String = "") {
    @Ignore constructor(id = 0, name = ", url = "") : this()
} 

Вы должны иметь в виду, что вы обычно используете классы данных, чтобы иметь такие методы, как toString и copy. Только это решение работает, чтобы избежать нежелательных ошибок во время выполнения.

Это сработало для меня:

@Entity
data class Site(
    @PrimaryKey(autoGenerate = true) var id: Long = 0),
    var name: String = "",
    var url: String = "",
    @Ignore var ignored: String? = null
)

Это работает для меня

@Entity
data class TaskDetail @Ignore constructor(
    @PrimaryKey(autoGenerate = true)
    var id:Long = 0,
    var taskId:Long = 0,
    var content:String = "")
{
    constructor():this(id = 0)
}

Я использую @Ignore, чтобы запретить предупреждение ROOM

Есть несколько хороших конструкторов, и Room выберет конструктор без аргументов. Вы можете использовать аннотацию @Ignore для удаления ненужных конструкторов.

И добавьте конструктор по умолчанию для ROOM.

@Entity
data class Site @JvmOverloads constructor(
    @ColumnInfo(name = "name") var name: String = "",
    @ColumnInfo(name = "url") var url: String = "",
    @PrimaryKey(autoGenerate = true) var id: Long = 0)

Неизменяемый класс модели для сайта. Для компиляции с Room мы могли бы использовать @JvmOverloads для обработки нескольких конструкторов.

Попробуйте изменить тип данных переменной с val на var:

ДО:

 @Entity
    data class Product(
            @PrimaryKey
            val id: String = "",
            val name: String = ""
    )

ПОСЛЕ:

@Entity
data class Product(
        @PrimaryKey
        var id: String = "",
        var name: String = ""
)

Я исправляю эту проблему, обновляя свою комнату и другие зависимости.

Просто попробуйте обновить все ваши зависимости, они должны работать без каких-либо изменений.

Спасибо

Здесь вы меняете базу данных своего приложения version и перезапустите программу agian, она будет работать:

@Database(entities = arrayOf(Site::class), version = 123) abstract class YourAppDatabase : RoomDatabase() {
    abstract fun yourDao(): YourDao
}

и вы также можете попробовать это data class:

    @Entity
    data class Site(@PrimaryKey(autoGenerate = true) var id: Long) {
    @Ignore constructor() : this(0)
    var name: String = "",
    var url: String = "",
}

и последняя инструкция: ваш первичный ключ id должен быть увеличен вручную.

Надеюсь, что это работает для вас.:)

Тест, чтобы показать, что вышеуказанные ответы являются недействительными.

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)}" }

возвращает Test с заданным именем: TestModel(id=5) и Testdata равно Testdata2 true

Ошибка вызвана изначально установленными переменными в конструкторе. Если у вас есть только один конструктор, измените свой код на этот.

@Entity
data class Site(
        val name: String,
        val url: String,
        @PrimaryKey(autoGenerate = true) val id: Long)

Если вам тоже нужен пустой конструктор, то вы должны сделать так

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

Просто оставлю мой ответ на случай, если это кому-нибудь поможет. Я столкнулся с той же проблемой, ни один из ответов выше не работал. Единственное, что сработало, менялось с data class к class, Я приглашаю любого попробовать тот же код и объяснить, почему он добился цели:

До

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

После

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

Это действительно странно, но я сомневаюсь, что это проблема с кешем Android Studio, потому что возвращаем ее обратно в data class заставляет ошибку появляться снова. Кажется, это какая-то проблема с полями коллекции. Я проверил конструктор в сгенерированном классе, и он выглядел нормально, я не знаю, почему сборка не удалась, даже когда конструктор генерировался правильно:

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();
}

Если кто-то может найти способ исправить это, не меняя data class в class пожалуйста, не стесняйтесь комментировать ниже.

Другие вопросы по тегам