Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Room Android : Entities and Pojos must have a usable public constructor

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)

Am integrating room into my existing project. While annotating a POJO, which implements Parcelable, with @Entity tag and making necessary changes, am getting this error. I already have an empty constructor in it. Any help would be appreciated.

@Entity(tableName = "Departments")
public class Department implements Parcelable {

    @PrimaryKey(autoGenerate = true)
    private Integer primaryId;
    private Integer id;
    private String departmentName;
    private String logoUrl;
    @Embedded
    private ArrayList<Template> templateList;

    public Department() {
    }

    protected Department(Parcel in) {
        this.primaryId = (Integer) in.readSerializable();
        this.departmentName = in.readString();
        this.logoUrl = in.readString();
        this.id = (Integer) in.readSerializable();
        this.templateList = in.createTypedArrayList(Template.CREATOR);
    }

    public static final Creator<Department> CREATOR = new Creator<Department>() {
        @Override
        public Department createFromParcel(Parcel in) {
            return new Department(in);
        }

        @Override
        public Department[] newArray(int size) {
            return new Department[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeSerializable(primaryId);
        dest.writeString(departmentName);
        dest.writeString(logoUrl);
        dest.writeSerializable(id);
        dest.writeTypedList(templateList);
    }

    public Integer getPrimaryId() {
        return primaryId;
    }

    public void setPrimaryId(Integer primaryId) {
        this.primaryId = primaryId;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLogoUrl() {
        return logoUrl;
    }

    public void setLogoUrl(String logoUrl) {
        this.logoUrl = logoUrl;
    }

    public String getDepartmentName() {
        return departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    public ArrayList<Template> getTemplateList() {
        return templateList;
    }

    public void setTemplateList(ArrayList<Template> templateList) {
        this.templateList = templateList;
    }
}

@Entity(tableName = "Templates")
public class Template implements Parcelable {

    @PrimaryKey(autoGenerate = true)
    private Integer primaryId;

    private Integer id;
    private String code;
    private String description;
    private Integer departmentId;
    @Embedded
    private ArrayList<Issue> issueList;

    public Template() {
    }

    private Template(Parcel in) {
        this.primaryId = (Integer) in.readSerializable();
        this.code = in.readString();
        this.description = in.readString();
        this.id = (Integer) in.readSerializable();
        this.departmentId = (Integer) in.readSerializable();
        this.issueList = in.createTypedArrayList(Issue.CREATOR);
    }

    public static final Creator<Template> CREATOR = new Creator<Template>() {
        @Override
        public Template createFromParcel(Parcel in) {
            return new Template(in);
        }

        @Override
        public Template[] newArray(int size) {
            return new Template[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeSerializable(primaryId);
        dest.writeString(code);
        dest.writeString(description);
        dest.writeSerializable(id);
        dest.writeSerializable(departmentId);
        dest.writeTypedList(issueList);
    }

    public Integer getPrimaryId() {
        return primaryId;
    }

    public void setPrimaryId(Integer primaryId) {
        this.primaryId = primaryId;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public ArrayList<Issue> getIssueList() {
        return issueList;
    }

    public void setIssueList(ArrayList<Issue> issueList) {
        this.issueList = issueList;
    }

    public Integer getDepartmentId() {
        return departmentId;
    }

    public void setDepartmentId(Integer departmentId) {
        this.departmentId = departmentId;
    }
}

@Entity(tableName = "Issues")
public class Issue implements Parcelable {

    @PrimaryKey(autoGenerate = true)
    private Integer primaryId;

    private Integer id;
    private String code;
    private String description;
    private Integer parentIssue;

    public Issue() {
    }

    protected Issue(Parcel in) {
        this.primaryId = (Integer) in.readSerializable();
        this.code = in.readString();
        this.description = in.readString();
        this.id = (Integer) in.readSerializable();
        this.parentIssue = (Integer) in.readSerializable();
    }

    public static final Creator<Issue> CREATOR = new Creator<Issue>() {
        @Override
        public Issue createFromParcel(Parcel in) {
            return new Issue(in);
        }

        @Override
        public Issue[] newArray(int size) {
            return new Issue[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeSerializable(primaryId);
        dest.writeString(code);
        dest.writeString(description);
        dest.writeSerializable(id);
        dest.writeSerializable(parentIssue);
    }

    public Integer getPrimaryId() {
        return primaryId;
    }

    public void setPrimaryId(Integer primaryId) {
        this.primaryId = primaryId;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getParentIssue() {
        return parentIssue;
    }

    public void setParentIssue(Integer parentIssue) {
        this.parentIssue = parentIssue;
    }
}
like image 982
Jai Avatar asked Jun 17 '17 12:06

Jai


2 Answers

Room assumes your entity class will be having only one constructor. But there is no such limitations, If you have multiple constructor then annotate one of them with

@Ignore

Room will ignore this constructor and compile without any error.

Example

@Entity(tableName = "Departments")
public class Department implements Parcelable {

@PrimaryKey(autoGenerate = true)
private Integer primaryId;
private Integer id;
private String departmentName;
private String logoUrl;
@Embedded
private ArrayList<Template> templateList;

/**Room will ignore this constructor
**/
@Ignore
public Department() {
}

protected Department(Parcel in) {
    this.primaryId = (Integer) in.readSerializable();
    this.departmentName = in.readString();
    this.logoUrl = in.readString();
    this.id = (Integer) in.readSerializable();
    this.templateList = in.createTypedArrayList(Template.CREATOR);
}
}
like image 145
Pinakin Kansara Avatar answered Oct 23 '22 05:10

Pinakin Kansara


I'm not sure why you are getting your specific constructor error. That said your code will error from embedding the ArrayList. @Embedded is not meant to be used this way. @Embedded allows you to flatten your POJO structure when storing it. Nested POJO properties will appear as if they had been properties on the parent POJO. Using Embedded on a List is the same as asking it to flatten the properties of the ArrayList object and store them, not flatten the list items and store them.

The appropriate measure is to transition into a foreign key, primary key relationship. An alternative solution is to create a new POJO that contains your list of items (ie Templates, with an 's'). This would contain an ArrayList of Template objects. You would then define a converter that converts the POJO to a json/comma seperated list, and stores it in a single column that by default would be called "templates". Here is a link to this approach : Android room persistent library - TypeConverter error of error: Cannot figure out how to save field to database"

Hope this helps.

like image 44
Jack Dalton Avatar answered Oct 23 '22 07:10

Jack Dalton