web-dev-qa-db-ja.com

複数のコンストラクターが適切なエラーであるため、部屋はコンストラクターを選択できません

私はAndroid kotlinプロジェクトに永続ライブラリを実装しようとしますが、コンパイル時にこのエラーをキャッチします。

エラー:複数のコンストラクターが適しているため、部屋はコンストラクターを選択できません。 @Ignoreを使用して、不要なコンストラクタに注釈を付けてください。

エラーコード:

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

Kotlinは明らかに、デフォルトの引数値を持つ単一のKotlinコンストラクターに対して複数のJavaコンストラクターを生成します。作業コードは次を参照してください。

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

上記の解決策はどれもうまくいきませんが、エラーを引き起こす可能性があります。

Kotlinの Data Class は、デフォルトのコンストラクターを使用していくつかのメソッドを生成します。つまり、 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を使用して2番目のコンストラクタを追加する必要があります。

@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などのメソッドを作成することに注意してください。このソリューションのみが、実行中の不要なバグを回避するために機能しています。

6
Emanuel S

これは私のために働いた:

@Entity
data class Site(
    @PrimaryKey(autoGenerate = true) var id: Long = 0),
    var name: String = "",
    var url: String = "",
    @Ignore var ignored: String? = null
)
2
Edwin Bello
@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を使用して複数のコンストラクターを処理できます。

1
Dhiraj Himani

変数のデータ型をvalからvarに変更してみてください。

前:

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

AFTER:

@Entity
data class Product(
        @PrimaryKey
        var id: String = "",
        var name: String = ""
)
1
m.fahad butt

これは私のために働く

@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のデフォルトコンストラクターを追加します。

1
Zebulon Li

ここで、アプリデータベース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)}" }

名前が設定されたテストを返します:TestModel(id = 5)およびTestdataはTestdata2に等しいtrue

0
SpkingR

エラーは、コンストラクターで変数を最初に設定したことが原因です。コンストラクターが1つしかない場合は、コードをこれに変更します。

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