Android Architecture Components: Using Enums
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;
}
}
}
I encountered a similar problem. Devrim's answer to the subject was very helpful. However my entity have nullable one.
In this case, the insert operation returns an error. This is caused by the primitive "code" member in the enum type.
I have developed the following implemantation to resolve this error.
First I fixed the enum type as follows.
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;
}
}
Then I updated the entity as follows.
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;
}
}
So, I could manage nullable enum property in Room database.
I hope I've been able to help with a similar situation.
Happy coding.