Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One-to-many relation in Room

I've been using SugarDB for most of my projects in the past. It was easy to use and satisfied most of my requirements but since that project has been abandoned, decided to look at alternatives and Room seems like the best option.

However, some basic things are quite confusing in Room. My Object uses Gson to populate data from a webservice, and as such as links to other objects. As an example, consider the classes below:

@Entity
public class TestModel
{
    @PrimaryKey(autoGenerate = true)
    private int id;
    private String name;
    private String age;
    private List<Book> issuedBooks;
}

public class Book
{
    private String title;
    private int ISBN;
}

Now if my first class is annotated as the Entity, will this automatically treat classes referenced inside it as entities as well?

If I save an object of TestModel, will it save the list of Books with it to the database?

like image 814
Asim Avatar asked Jan 25 '18 13:01

Asim


People also ask

What is an example of a one-to-many relationship?

Some common examples of one-to-many relationships are: A car maker makes many different models, but a particular car model is built only by a single car maker. One customer may make several purchases, but each purchase is made by a single customer.

Is room a relational database?

Because SQLite is a relational database, you can define relationships between entities. Even though most object-relational mapping libraries allow entity objects to reference each other, Room explicitly forbids this.

What is entity in room in Android?

A Room entity includes fields for each column in the corresponding table in the database, including one or more columns that comprise the primary key. The following code is an example of a simple entity that defines a User table with columns for ID, first name, and last name: Kotlin Java.

What is ORM how does it work in Android?

An ORM stands for Object Relational Mapping and will map database tables to entities. For a Persons table for example, a class Person will be created. You will then be able to edit the fields of the class and when you call a "save" method, the database table will be updated.


2 Answers

I guess you can do it this way.

@Entity
public class TestModel {
    @PrimaryKey
    public int id;          // TestModel id
    public String name;
    public String age;
}

@Entity
public class Book {
    @PrimaryKey
    public int id;          // Book id
    public int testModelId; // TestModel id
    public String title;
    public int ISBN;
}

public class TestModelWithBooks {
   @Embedded
   public TestModel testModel;

   @Relation(parentColumn = "id", entityColumn = "testModelId", entity = Book.class)
   public List<Book> books;
}

For their Dao, you can write it this way.

@Dao
public interface TestModelDao {
    @Query("SELECT * FROM TestModel")
    public List<TestModelWithBooks> loadTestModelsWithBooks();
}
like image 145
Cheok Yan Cheng Avatar answered Sep 19 '22 15:09

Cheok Yan Cheng


will this automatically treat classes referenced inside it as entities as well?

No. In fact, I would expect your code to fail to compile. You would need to:

  • Make Book be an @Entity
  • Remove issuedBooks from TestModel
  • Set up a @ForeignKey relationship between Book and TestModel

If I save an object of TestModel, will it save the list of Books with it to the database?

No.

Room is not an ORM. Room is a thin object wrapper around SQLite. @Entity and @ForeignKey model the table structure. IMHO, the simplest way to think of Room as it being DTOs to the database. Your model objects that represent your object graph are not the entities, but instead are built from the entities. This is akin to how responses from a Web service (e.g., Retrofit) are DTOs to the server, and you may need to map from those objects to the "real" model objects that you want to use in the app.

like image 45
CommonsWare Avatar answered Sep 19 '22 15:09

CommonsWare