9

I am working on an android project where have to store some data in the local DB (Room). One of the functionality which I have to provide is to store the data in the local DB in different languages, for example if I have information for food, this information has to be stored in English, German, French and so on.

The structure of my DB is something like that:

@Entity(tableName = "food")
public class Food{

}

@Entity(tableName = "food_fr")
public class FoodFr{

}

@Entity(tableName = "food_de")
public class FoodDe{

}

My question is how I can have these three different tables (on different languages) with same columns and the @Dao object return one common (parent) object for all of them?

I am not really sure that is possible at all, but if someone has a solution for that case, please help.

Thanks in advance :)

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
MrVasilev
  • 1,503
  • 2
  • 17
  • 34
  • 2
    Why not have one table, with a language column to distinguish between the three languages? – CommonsWare May 08 '18 at 12:53
  • @CommonsWare, because I already create a structure of my DB and build a lot of code based on that structure. For now I am looking for a way how to extend not to modificate – MrVasilev May 08 '18 at 13:02
  • @CommonsWare is right, and it would be harder to control or modify all tables later. You should modify your code – Abdullah Tellioglu May 08 '18 at 13:10

2 Answers2

15

The best solution is to have a single table, rather than three tables. Use a column to distinguish between the three languages (e.g., a language column with en, fr, and de values). Since you will be rewriting much of your existing code anyway, switching from three tables to one would not seem to be a major impediment.

That being said, to keep your existing three-table structure, have Food, FoodFr, and FoodDe all extend from a common base class (e.g., BaseFood), where you define your fields/columns.

For queries, you would need to have your DAO handle all four cases (three specific language tables, plus a method to combine the results for all three), such as:

@Query("SELECT * FROM Food")
List<Food> getAllFood();

@Query("SELECT * FROM FoodFr")
List<FoodFr> getAllFrenchFood();

@Query("SELECT * FROM FoodDe")
List<FoodDe> getAllGermanFood();

@Transaction
List<BaseFood> getAllFoodAcrossAllThreeLanguages() {
  ArrayList<BaseFood> result=new ArrayList<>();

  result.addAll(getAllFood());
  result.addAll(getAllFrenchFood());
  result.addAll(getAllGermanFood());

  return result;
}
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • thank you very much you push me to modify my current logic :) Now I already did it and just make a composite PrimaryKey for the table Food (@Entity(primaryKeys{"id", "language_id"})). Everything works great. Thank you again – MrVasilev May 08 '18 at 14:44
  • 1
    nice suggestion @CommonsWare – maveroid Aug 08 '18 at 11:49
  • trying to achieve same but when using transaction build fails in DaoImpl class. This error shows up if I try to return from transaction. – Navdroid Aug 14 '18 at 05:54
  • @Navdroid: You might consider asking a separate Stack Overflow question where you can provide a [mcve] (source code plus the exact build error message). – CommonsWare Aug 14 '18 at 11:48
  • @CommonsWare - https://stackoverflow.com/questions/51852669/fetching-data-from-multiple-tables-in-single-transaction-using-room . Please look into this. Thanks – Navdroid Aug 15 '18 at 03:46
  • Having 3 tables with a common parent Object unfortunately is not an option with Kotlin because inheritance with **Data** classes is not possible. See [**Extend data class in Kotlin**](https://stackoverflow.com/questions/26444145/extend-data-class-in-kotlin). I am going to move forward with the one table approach for my app that has a **Content** object that can be saved to 3 different categories thus needs 3 Room queries. – AdamHurwitz Sep 09 '18 at 20:42
3

You can merge different tables with @Embedded annotation. https://developer.android.com/reference/android/arch/persistence/room/Embedded?authuser=4

And in Dao class write a sql query that merge your tables with inner join and return that merged object.

You can look at my example application. https://github.com/volkansahin45/Moneycim

In Model/Pojo folder there is a Spending class and in Model/Dao folder there is SpendingDao class

VolkanSahin45
  • 1,922
  • 12
  • 25