In this blog, we will learn about saving complex objects using android room library.
If you have no knowledge about the android room, then you should first read this article:
After reading this article, you get to know how easy now it is to create a table in your android application. It is just like creating a model class ( a Custom object).
This room library has saved us a lot from the boilerplate code that we used to write for creating a table.But when you start using in the real world scenarios, then you see that you have complex models which have one or more list of objects and some child objects. And room only recognizes the primitive datatypes.
Now you have two options :
- To restructure your model class and save the inner objects into separate tables and then manage them through relations.
OR - To use @Embedded annotation.
Before we go further, let’s first understand what this @Embedded annotation is and what it will do?
As per official docs: @Embedded can be used as an annotation on a field of an Entity or Pojo to signal that nested fields (i.e. fields of the annotated field’s class) can be referenced directly in the SQL queries.
What this means is that if you have some child object in your Model( Entity) class, then when creating the table, the number of columns will be automatically increased to fit in your child object as well. The total number of columns now will be ( Number of columns in your model class + number of columns(fields that make up your object) in your child object class).
But this will only help you save the child object and not the list as we have still not used anything that will help the room to identify the list of objects. for this purpose, we will use type converters.
Now, You will be wondering what exactly is a Type Converter?
Type Converter specifies additional type converters that Room can use. The TypeConverter is added to the scope of the element so if you put it on a class/interface, all methods/fields in that class will be able to use the converters.
Now enough of theory and explanation, let’s have a look at the coding part.
CODE :
Model(Object) Class: This class I need to save to my table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
@Entity(tableName = "my_table") public class MyData { @PrimaryKey(autoGenerate = true) private int id; @ColumnInfo(name = "ListData") @TypeConverters(DataTypeConverter.class) private List<MyListObject> mList = null; @Embedded private User mUser; public MyData() { } public int getId() { return id; } public void setId(int id) { this.id = id; } public List<MyListObject> getList() { return mList; } public void setList(List<MyListObject> list) { this.mList = list; } public User getUser() { return mUser; } public void setUser(User user) { this.mUser = user; } } |
User.class :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class User { @ColumnInfo(name = "first_name") private String firstName; @ColumnInfo(name = "last_name") private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } } |
DataTypeConverter.class: This class will help Android room to convert the list into a primitive data type ( String) and save it in the table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class DataTypeConverter { private static Gson gson = new Gson(); @TypeConverter public static List<MyListObject> stringToList(String data) { if (data == null) { return Collections.emptyList(); } Type listType = new TypeToken<List<MyListObject>>() {}.getType(); return gson.fromJson(data, listType); } @TypeConverter public static String ListToString(List<MyListObject> someObjects) { return gson.toJson(someObjects); } } |
Ok, till now we understood the use of type converter, but still wondering what the @Embedded annotation did.
When Room will create your table.(my_table in our case). The table will have 4 columns ( 2 for the object that you are using and 2 for the embedded child object).
That’s it. Hope this helps you understand the room architecture and how you will be able to save the real world objects using room easily.