ルーム永続ライブラリと統合しています。 Kotlinには次のようなデータクラスがあります。
@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
および@PrimaryKey
注釈は、部屋ライブラリ用です。ビルドしようとすると、エラーで失敗します:
Error:Cannot find setter for field.
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.
また、デフォルトのコンストラクタを提供しようとしました:
@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, "", "", "")
}
しかし、これもうまくいきません。注意すべきことは、このKotlinクラスをゲッターとセッターを含むJavaクラスに変換すれば機能するということです。どんな助けも大歓迎です!
フィールドにはval
のマークが付けられているため、事実上最終フィールドであり、セッターフィールドはありません。
val
をvar
に切り替えてみてください。また、フィールドを初期化する必要があります。
@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 = ""
)
誰もが知っているかどうかはわかりませんが、is
からRoom
に始まる列を持つことはできません。たとえば、あなたはこのようなことはできません
@Entity(tableName = "user")
data class User (
@PrimaryKey var id: Long? = null,
var userName: String = "",
var isConnectedToFB: Boolean = false,
)
ルームdbライブラリJavaコード生成に問題があります。
オプションフィールドisFavorite
を使用していました。同じエラーが表示され、フィールド名をfavorite
に変更してからコンパイルします。
var isFavorite: Int? = 0,
の前に正常に動作するvar favorite: Int? = 0,
を変更した後、ありがとう
https://stackoverflow.com/a/46753804/291414 に従って、自動生成された主キーがある場合は、次のように記述する必要があります。
@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
}
@PrimaryKey
はクラス本体内に記述され、修飾子var
を含むことに注意してください。
後で異なるパラメーターを使用してデータベースの行を更新する場合は、次の行を使用します。
val newStory = story.copy(by = "new author", title = "new title") // Cannot use "id" in object cloning
newStory.id = story.id
dao.update(newStory)
更新
私はまだAndroidXを使用せず、Roomは「Android.Arch.persistence.room:runtime:1.1.1」です。
このクラスはSerializable
から拡張できます。ただし、Parcelable
から拡張する場合は、(id
変数に対して)警告が表示されます:Property would not be serialized inro a 'Parcel'. Add '@IgnoredOnParcel' annotation to remove this warning
:
次に、id
を本体からコンストラクターに移動しました。 Kotlinでは、@Parcelize
を使用してParcelable
クラスを作成します。
@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
これはバグであり、部屋2.1.0-alpha01
で修正されています
https://developer.Android.com/jetpack/docs/release-notes#october_8_2018
バグの修正
- ルームは、データクラスでKotlinのプライマリコンストラクターを適切に使用するようになり、フィールドを変数として宣言する必要がなくなりました。 b/105769985
Javaでこのエラーが発生しました。
Javaでは、is
またはis_
で始まる列を使用できません。
列の名前を変更してみてください。
別の解決策:
フィールドをコンストラクターに渡してコンストラクター引数で初期化するか、そのセッターを作成する必要があります。
例:
public MyEntity(String name, ...) {
this.name = name;
...
}
public void setName(String name) {
this.name = name;
}
エンティティでval
不変性を使用できるようにする場合は、可能です。
val
をdefault value
とともに使用できます。例:@Entity("tbl_abc")
data class Abc(
@PrimaryKey
val id: Int = 0,
val isFavourite: Boolean = false
)
以前は、上記のスニペットはCannot find setter for field
のエラーをスローします。 var
への変更は優れた回避策ですが、エンティティクラスは外部呼び出しから不変であることを好みます
これの別の原因は、フィールドの名前付けかもしれません。事前定義されたキーワードのいずれかを使用すると、同じエラーが発生します。たとえば、列に「is_active」という名前を付けることはできません。
2019年に誰かがこのスレッドに出くわした場合、これがなぜ機能するのかオンラインで数時間かけて掘り下げた後の更新ですが、そうではありません。
val
を使用すると、AndroidXバージョン(androidx.room:room-<any>:2.*
)を使用している場合は期待どおりに機能しますが、古いAndroid.Arch.persistence.room:<any>:1.1.1
を使用する場合は機能せず、バージョン2.*
はこの後者のリポジトリでリリースされました。
編集:タイプミス