Is it possible to use an Enum type as an embedded field in an Entity class with the new Android Architecture Components and Room Persistence Library?
My Entity (with embedded 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; } } }
My 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(); } }
When I compile this I get an error saying Error:(52, 12) error: Entities and Pojos must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).
Update 1 My SyncEntity class:
/** * Base class for all Room entities that are synchronized. */ @Entity public class SyncEntity { @ColumnInfo(name = "created_at") Long createdAt; @ColumnInfo(name = "updated_at") Long updatedAt; }
I can use enum values at Room
with TypeConverters
. There are some parts to change at your code:
1) You must declare your Entity's fields public or they must have public getters/setters. Or you'll get below error:
yourField is not public in YourEntity; cannot be accessed from outside package
2) You don't need the @Embedded
annotation for your status
field. It is for nested objects. More from docs.
3) You didn't use the @TypeConverters
annotation at the correct place. In your case it can be set above the status
field. More from docs.
4) You must define a constructor for your Entity or you'll get below error:
Entities and Pojos must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).
You can define an empty constructor to skip this error.
5) Use int instead of Integer in your TypeConverter.
Sum; below works as expected:
@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; } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With