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.
(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; });