I am using Room in my Android App (Java) and there I have two entities with a 1:many relation.
Lens entity One lens can have multiple wears.
@Entity(tableName = "lens_table")
public class Lens {
@PrimaryKey(autoGenerate = true)
private int lensId;
private String name;
}
Wear entity One wear can only relate to one lens.
@Entity(tableName = "wear_table",
foreignKeys = {@ForeignKey(
entity = Lens.class,
parentColumns = "lensId",
childColumns = "fk_lensId",
onDelete = ForeignKey.CASCADE)},
indices = {@Index("fk_lensId")})
public class Wear {
@PrimaryKey(autoGenerate = true)
private int wearId;
private String name;
private int fk_lensId;
}
So far so good. I am fine with the "standard" queries (create, get all, update, delete,...) so far, where a lot of documentation is around. I also was successful implementing the query to get all lenses with their wears based on below relation.
public class LensWithWears {
@Embedded
public Lens lens;
@Relation(
parentColumn = "lensId",
entityColumn = "fk_lensId"
)
public List<Wear> wears;
}
But now I need to query the following information:
Get a single wear with the associated lens by looking up the wearId
The relationship class I am currently using looks like following:
public class WearWithLens {
@Embedded
public Wear wear;
@Relation(
parentColumn = "wearId",
entityColumn = "lensId"
)
public Lens lens;
}
And the Dao Query looks like that:
@Query("SELECT * FROM wear_table WHERE wearId = :wearId LIMIT 1")
LiveData<WearWithLens> getWearWithLensByWearId(int wearId);
My code obviously does not work, otherwise I would not ask... The problem is, that an object WearWithLens is returned, but the lens object in it is always null.
In other words, I would like to query a Wear, which has a 1:1 relation to a lens and get both objects together in the class WearWithLens.
Can somebody tell me how the query should look like?
Thanks!
CodePudding user response:
The parent column needs to be the column that forms the relationship between the two. That is it should be the fk_lensId
column.
So :-
public class WearWithLens {
@Embedded
public Wear wear;
@Relation(
parentColumn = "fk_lensId",
entityColumn = "lensId"
)
public Lens lens;
}
As an example
- not using
LiveData<WearWithLens> getWearWithLensByWearId(int wearId);
but insteadWearWithLens getWearWithLensByWearId(int wearId);
for convenience and brevity. - using your classes/entities with getters and setters added and also additional constructors to reduce the coding
- and obviously the @Relationship as above.
With the following :-
db = TheDatabase.getInstance(this);
dao = db.getAllDao();
int l1id = (int) dao.insert(new Lens("Lens1"));
int l2id = (int) dao.insert(new Lens("Lens2"));
int l3id = (int) dao.insert(new Lens("Lens3"));
dao.insert(new Wear("Wear1 child of Lens1",l1id));
dao.insert(new Wear("Wear2 child of Lens1",l1id));
dao.insert(new Wear("Wear3 child of Lens1",l1id));
dao.insert(new Wear("Wear4 child of Lens2",l2id));
dao.insert(new Wear("Wear5 child of Lens2",l2id));
dao.insert(new Wear("Wear6 child of Lens2",l2id));
dao.insert(new Wear("Wear7 child of Lens3",l3id));
for (Wear wear: dao.getAllWears()) {
WearWithLens currentWearWithLens = dao.getWearWithLensByWearId(wear.getWearId());
Log.d("DBINFO","Current Wear is " currentWearWithLens.wear.getName() " parent Lens is " currentWearWithLens.lens.getName());
}
The Result is:-
2021-12-09 06:34:58.105 D/DBINFO: Current Wear is Wear1 child of Lens1 parent Lens is Lens1
2021-12-09 06:34:58.110 D/DBINFO: Current Wear is Wear2 child of Lens1 parent Lens is Lens1
2021-12-09 06:34:58.112 D/DBINFO: Current Wear is Wear3 child of Lens1 parent Lens is Lens1
2021-12-09 06:34:58.114 D/DBINFO: Current Wear is Wear4 child of Lens2 parent Lens is Lens2
2021-12-09 06:34:58.115 D/DBINFO: Current Wear is Wear5 child of Lens2 parent Lens is Lens2
2021-12-09 06:34:58.116 D/DBINFO: Current Wear is Wear6 child of Lens2 parent Lens is Lens2
2021-12-09 06:34:58.120 D/DBINFO: Current Wear is Wear7 child of Lens3 parent Lens is Lens3