Android Room: How to model relationships? Android Room: How to model relationships? sqlite sqlite

Android Room: How to model relationships?


You can use @Relation annotation to handle relations at Room.

A convenience annotation which can be used in a Pojo to automatically fetch relation entities. When the Pojo is returned from a query, all of its relations are also fetched by Room.

See document.

(Google's document has confusing examples. I have written the steps and some basic explanation at my another answer. You can check it out)


I created a simple Convenience Method that populates manually a one to many relationship.So for example if you have a one to many between Country and City , you can use the method to manually populate the cityList property in Country.

/** * @param tableOne The table that contains the PK. We are not using annotations right now so the pk should be exposed via a getter getId(); * @param tableTwo The table that contains the FK. We are not using annotations right now so the Fk should be exposed via a getter get{TableOneName}Id(); eg. getCountryId(); * @param <T1>     Table One Type * @param <T2>     Table Two Type * @throws NoSuchFieldException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws InvocationTargetException */private static <T1, T2> void oneToMany(List<T1> tableOne, List<T2> tableTwo) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {    String tableOneName = tableOne.get(0).getClass().getSimpleName();    String tableTwoName = tableTwo.get(0).getClass().getSimpleName();    for (T1 t1 :            tableOne) {        Method method = t1.getClass().getMethod("getId");        Integer pkId = (Integer) method.invoke(t1);        List<T2> listForCurrentId = new ArrayList<>();        for (T2 t2 : tableTwo) {            Method fkMethod = t2.getClass().getDeclaredMethod("get".concat(tableOneName).concat("Id"));            Integer fkId = (Integer) fkMethod.invoke(t2);            if (pkId == fkId) {                listForCurrentId.add(t2);            }        }        Method tableTwoList = t1.getClass().getMethod("set".concat(tableTwoName).concat("List"), List.class);        tableTwoList.invoke(t1, listForCurrentId);    }}

This is how I use it .

   SystemDefaults systemDefaults = new SystemDefaults();    return Single.zip(systemDao.getRoles(), systemDao.getCountries(), systemDao.getCities(), (roles, countries, cities) -> {        systemDefaults.setRoles(roles);        *ConvenienceMethods.oneToMany(countries,cities);*        systemDefaults.setCountries(countries);        return systemDefaults;    });