新しいAndroid Architecture Components and Room Persistence LibraryでEntityクラスの埋め込みフィールドとしてEnumタイプを使用することは可能ですか?
私のエンティティ(埋め込みEnumを使用):
@Entity(tableName = "tasks")
public class Task extends SyncEntity {
@PrimaryKey(autoGenerate = true)
String taskId;
String title;
/** Status of the given task.
* Enumerated Values: 0 (Active), 1 (Inactive), 2 (Completed)
*/
@Embedded
Status status;
@TypeConverters(DateConverter.class)
Date startDate;
@TypeConverters(StatusConverter.class)
public enum Status {
ACTIVE(0),
INACTIVE(1),
COMPLETED(2);
private int code;
Status(int code) {
this.code = code;
}
public int getCode() {
return code;
}
}
}
私のTypeConverter:
public class StatusConverter {
@TypeConverter
public static Task.Status toStatus(int status) {
if (status == ACTIVE.getCode()) {
return ACTIVE;
} else if (status == INACTIVE.getCode()) {
return INACTIVE;
} else if (status == COMPLETED.getCode()) {
return COMPLETED;
} else {
throw new IllegalArgumentException("Could not recognize status");
}
}
@TypeConverter
public static Integer toInteger(Task.Status status) {
return status.getCode();
}
}
これをコンパイルすると、「Error:(52、12)error:Entities and Pojos must have a public constructor。」というエラーが表示されます。空のコンストラクターまたはパラメーターがフィールドに一致するコンストラクター(名前とタイプ)を持つことができます。
更新1 My SyncEntityクラス:
/ ** *同期されるすべての会議室エンティティの基本クラス。 * /
@Entity
public class SyncEntity {
@ColumnInfo(name = "created_at")
Long createdAt;
@ColumnInfo(name = "updated_at")
Long updatedAt;
}
Room
の列挙値をTypeConverters
とともに使用できます。コードで変更する部分がいくつかあります。
1)エンティティのフィールドをパブリックとして宣言するか、パブリックのゲッター/セッターが必要です。または、以下のエラーが表示されます:
yourFieldはYourEntityでパブリックではありません;外部パッケージからアクセスできません
2)status
フィールドに@Embedded
注釈は必要ありません。ネストされたオブジェクト用です。 ドキュメントの詳細
3)@TypeConverters
注釈を正しい場所で使用していません。あなたの場合、status
フィールドの上に設定できます。 ドキュメントの詳細
4)エンティティのコンストラクタを定義する必要があります。そうしないと、以下のエラーが発生します。
エンティティとPojoには、使用可能なパブリックコンストラクターが必要です。空のコンストラクターまたはパラメーターがフィールドに一致するコンストラクター(名前とタイプによる)を持つことができます。
このエラーをスキップするには、空のコンストラクターを定義できます。
5)TypeConverterでIntegerの代わりにintを使用します。
和;以下は期待どおりに動作します:
@Entity(tableName = "tasks")
public class Task extends SyncEntity {
@PrimaryKey(autoGenerate = true)
public String taskId;
public String title;
/** Status of the given task.
* Enumerated Values: 0 (Active), 1 (Inactive), 2 (Completed)
*/
@TypeConverters(StatusConverter.class)
public Status status;
@TypeConverters(DateConverter.class)
public Date startDate;
// empty constructor
public Task() {
}
public enum Status {
ACTIVE(0),
INACTIVE(1),
COMPLETED(2);
private int code;
Status(int code) {
this.code = code;
}
public int getCode() {
return code;
}
}
}
同様の問題が発生しました。この問題に対するDevrimの答えはとても役に立ちました。ただし、エンティティにはnull値を許可するエンティティがあります。
この場合、挿入操作はエラーを返します。これは、列挙型のプリミティブな「コード」メンバーが原因です。
このエラーを解決するために、次の実装を開発しました。
最初に列挙型を次のように修正しました。
package com.example.models.entities.enums;
import androidx.room.TypeConverter;
public enum Status {
ACTIVE(0),
INACTIVE(1),
COMPLETED(2);
private final Integer code;
Status(Integer value) {
this.code = value;
}
public Integer getCode() {
return code;
}
@TypeConverter
public static Status getStatus(Integer numeral){
for(Status ds : values()){
if(ds.code == numeral){
return ds;
}
}
return null;
}
@TypeConverter
public static Integer getStatusInt(Status status){
if(status != null)
return status.code;
return null;
}
}
次に、エンティティを次のように更新しました。
package com.example.models.entities;
import com.example.models.TypeConverters.DateConverter;
import com.example.models.entities.enums.Status;
import Java.util.Date;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import androidx.room.TypeConverters;
@Entity(tableName = "tasks")
@TypeConverters({Status.class, DateConverter.class})
public class Task extends SyncEntity {
@PrimaryKey(autoGenerate = true)
String taskId;
@NonNull
String title;
/** Status of the given task.
* Enumerated Values: 0 (Active), 1 (Inactive), 2 (Completed)
*/
@Nullable
Status status;
@NonNull
Date startDate;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
@NonNull
public String getTitle() {
return title;
}
public void setTitle(@NonNull String title) {
this.title = title;
}
@Nullable
public Status getStatus() {
return status;
}
public void setStatus(@Nullable Status status) {
this.status = status;
}
@NonNull
public Date getStartDate() {
return startDate;
}
public void setStartDate(@NonNull Date startDate) {
this.startDate = startDate;
}
}
そのため、Roomデータベースでnull許容列挙型プロパティを管理できました。
同様の状況で私が助けられたことを願っています。
ハッピーコーディング。