Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Room @Embedded annotation compilation fails for @NonNull annotated constructor parameters of a POJO defined in a library module

I have a POJO which I am embedding in a Room Entity; Please note that the POJO is defined in a library module;

@Entity
public class Person {
    @PrimaryKey
    @NonNull
    private String uuid;

    @Embedded
    @NonNull
    private Address address;

    public Person(@NonNull String uuid, @NonNull Address address) {
        this.uuid = uuid;
        this.address = address;
    }

    @NonNull
    public String getUuid() {
        return uuid;
    }

    @NonNull
    public Address getAddress() {
        return address;
    }
}


public class Address {
    @NonNull
    private String street;

    @NonNull
    private String city;

    public Address(@NonNull String street, @NonNull String city) {
        this.street = street;
        this.city = city;
    }

    @NonNull
    public String getStreet() {
        return street;
    }

    @NonNull
    public String getCity() {
        return city;
    }
}


@Dao
public interface PersonDao {
    @Query("SELECT * FROM Person")
    List<Person> getPersons();
}



@TypeConverters(DateConverter.class)
@Database(entities = {Person.class}, version = 1, exportSchema = false)
public abstract class PersonDb extends RoomDatabase {
    private static volatile PersonDb INSTANCE;

    public abstract PersonDao getPersonDao();
}

Compilation fails with

"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)." Error:Cannot find setter for field.

If I remove @NonNull annotation from the constructors parameters to Address POJO, the code compiles fine. Also, if the same POJO is in the app module, code compiles.

As can be seen, Address class does have a public constructor.

What am I missing here? What is the definition of usable constructor in Room's perspective? Or it is an issue with Room?

like image 696
nightlytrails Avatar asked Mar 05 '18 17:03

nightlytrails


1 Answers

The documentation says: "To persist a field, Room must have access to it. You can make a field public, or you can provide a getter and setter for it. If you use getter and setter methods, keep in mind that they're based on JavaBeans conventions in Room."

uuid and address are declared as private in Person, you have getters for those but no setters. So you can create setters or declare them as public.

like image 113
yak27 Avatar answered Oct 21 '22 12:10

yak27