Skip to content
Advertisement

Merging multiple LiveData sources?

To make it easier to visualize my problem I drew the following: enter image description here

I am using a RoomDatabase, a Repository, a Viewmodel and Livedata. Areas have a 1 to n relationship with Gateways and Gateways a 1 to n relationship with Items. I created both an AreaWithGateways entity and a GatewayWithItems entity.

Items can move from a gateway to another, which is why I observe them with Livedata to keep track of which Gateway they’re in. My problem now is that I found myself in need to also keep track of which Items are in which Areas and I can’t figure out how to do that.

I’ve thought of merging the LiveData of each Gateway together and observing that using MediatorLiveData but I didn’t really understand how to use it. Or maybe it’s possible to create an Entity AreaWithGatewayswithItems?

Any insight would be appreciated

Edit: I am adding some code to make the problem a bit clearer

This is the Area Entity

@Entity(tableName = "area_table")
public class Area {

    @PrimaryKey(autoGenerate = false)
    private int areaId;

    private String areaName;
    private float wertX;
    private float wertY;
    private Boolean isDrawn;


    public int getAreaId() {
        return areaId;
    }

    public void setAreaId(int areaId) {
        this.areaId = areaId;
    }

    public String getAreaName() {
        return areaName;
    }

    public float getWertX() {
        return wertX;
    }

    public float getWertY() {
        return wertY;
    }

    public Boolean getDrawn() {
        return isDrawn;
    }

    public Area(int areaId, String areaName, float wertX, float wertY, Boolean isDrawn) {
        this.areaId = areaId;
        this.areaName = areaName;
        this.wertX = wertX;
        this.wertY = wertY;
        this.isDrawn = isDrawn;
    }
}

The Gateway Entity:

@Entity(tableName = "gateway_table")
public class Gateway {
    
    private float temp;
    private String title;
    private int areaId;


    @PrimaryKey(autoGenerate = false)
    private int gatewayId;

    public int getGatewayId() {
        return gatewayId;
    }

    public void setGatewayId(int gatewayId) {
        this.gatewayId = gatewayId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public float getTemp() {
        return temp;
    }

    public void setTemp(float temp) {
        this.temp = temp;
    }

    public int getAreaId() {
        return areaId;
    }

    public Gateway(int areaId, int gatewayId, String title) {
        this.title = title;
        this.areaId = areaId;
        this.gatewayId = gatewayId;
    }
}

And the “Item” Entity:

@Entity(tableName = "cow_table")
public class Cow {

    private int age;
    private String sex;
    private String name;
    private boolean drawn;
    private int gatewayId;
    private String raceId;


    @PrimaryKey(autoGenerate = false)
    private int cowId;

    public int getCowId() {
        return cowId;
    }

    public void setCowId(int cowId) {
        this.cowId = cowId;
    }

    public String getName() {
        return name;
    }


    public boolean isDrawn() {
        return drawn;
    }

    public int getAge() {
        return age;
    }

    public String getSex() {
        return sex;
    }

    public void setDrawn(boolean drawn) {
        this.drawn = drawn;
    }

    public int getGatewayId() {
        return gatewayId;
    }

    public String getRaceId() {
        return raceId;
    }

    public Cow(int age, int cowId, int gatewayId,String name, String raceId, String sex, boolean drawn) {

        this.age = age;
        this.cowId = cowId;
        this.sex= sex;
        this.name = name;
        this.drawn = drawn;
        this.gatewayId = gatewayId;
        this.raceId = raceId;
    }


}

And this is the relation “AreaWithGateways”:

public class AreaWithGateways {

    @Embedded
    private Area area;

    @Relation(parentColumn = "areaId",
    entityColumn = "areaId")
    private List<Gateway> gatewayList;

    public Area getArea() {
        return area;
    }

    public List<Gateway> getGatewayList() {
        return gatewayList;
    }

    public AreaWithGateways(Area area, List<Gateway> gatewayList) {
        this.area = area;
        this.gatewayList = gatewayList;
    }
}

As well as GatewaysWithCows:

public class GatewayWithCows {

    @Embedded
    private Gateway gateway;

    @Relation(parentColumn = "gatewayId",
            entityColumn = "gatewayId")
    private List<Cow> cowList;

    public Gateway getGateway() {
        return gateway;
    }

    public List<Cow> getCowList() {
        return cowList;
    }

    public GatewayWithCows(Gateway gateway, List<Cow> cowList) {
        this.gateway = gateway;
        this.cowList = cowList;
    }
}

I’ve been trying to find a way of getting all of the “items” in an Area as Livedata but still can’t figure it out. I feel like I should somehow use AreaWithGateways to add the LiveData items together but I can’t reach the items through the gateways, it has to be the other way around.

Answer

Or maybe it’s possible to create an Entity AreaWithGatewayswithItems?

Not an Entity as these are used to define tables BUT via POJO’s using @Embedded and @Relation annotation (e.g. your GatewayWithCows is a POJO).

I feel like I should somehow use AreaWithGateways to add the LiveData items together but I can’t reach the items through the gateways, it has to be the other way around.

You basically use a hierarchical approach but POJO’s so as you have GatewayWithCows then relate to this from Area as per :-

class AreaWithGatewayWithCows {

    @Embedded
    Area area;
    @Relation(entity = Gateway.class, parentColumn = "areaId",
            entityColumn = "areaId")
    List<GatewayWithCows> gatewayWithCowsList;

}
  • Note I missed the s after Gateway for the class name (and as such in the query below)

  • Note the use of entity = Gateway.class is required as the relationship is via the Gateway NOT via the GatewayWithCows (which isn’t a table).

The Query Dao could be as simple as :-

@Query("SELECT * FROM area_table")
List<AreaWithGatewayWithCows> getAreaWithGatewaysWithCows();
  • amended accordingly for LiveData.
  • note that if you use JOINS in the query then the any clauses such as WHERE will only affect the Area’s, not the underlying Gateways and Cows. That is irrespective of the query @Relation builds each Area with ALL Gateways related to that Area; and each Gateway gets ALL the Cows related to that Gateway.
Advertisement