Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Architecture Components: Using Enums

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; } 
like image 267
Bohsen Avatar asked Jun 12 '17 11:06

Bohsen


1 Answers

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;         }     } } 
like image 64
Devrim Avatar answered Oct 02 '22 08:10

Devrim