android / architecture-components-samples

Samples for Android Architecture Components.
https://d.android.com/arch
Apache License 2.0
23.42k stars 8.29k forks source link

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

Closed kumaraish closed 6 years ago

kumaraish commented 6 years ago

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?

Versions - implementation 'android.arch.persistence.room:runtime:1.1.0-alpha3' annotationProcessor 'android.arch.persistence.room:compiler:1.1.0-alpha3' gradle 3.0.1 Android Studio 3.0.1

florina-muntenescu commented 6 years ago

Feel free to ask this question on StackOverflow.

kumaraish commented 6 years ago

It is already asked there. No takers yet - https://stackoverflow.com/q/49115995/1363471 Thanks.

DarshanNair commented 6 years ago

Actually am also facing this same issue. Even many have faced this issue and reported over stackoverrlow but with no luck.

My observation: I found when the pojo is inside another library module, compiler does some name mangling (eg. Arg0, Args1... for parameters in pojo) So if the entity inside app module refer pojo in another module, it won't work as it expects parameters as arg0, arg1 (you could try to rename pojo parameter with args0,.., it will compile). But if we could disable the name mangling for embedded pojo somehow my hunch is it will work. Did you able to solve this problem?