Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Room - Handling List of Objects in an Object and querying result

Im working with Android's Room Database and am having some big problems understanding how to:

  1. When I add a Person to the database, it adds all its variables e.g. List<Shoe>,List<Pet> etc. to the database as well.
  2. Create relations such that when I retrieve a Person, all its fields are retrieved e.g Pet, Shoe, Shirt etc. (Not sure what type of query that is)

  3. Perform simple query e.g. Retrieve Person whereshoe.name= "boot";

I know you must use Foreign Key relationships with list of objects, otherwise with a single object one can use @Embed or @TypeConverter

Sample code is shown below;

@Entity(tableName = "person")
    public class Person {
        @PrimaryKey
        @NonNull
        private String personId;
        private List<Pet> pets;
        private List<Shoe> shoes;
        private List<Shirt> shirts;
    }

@Entity(foreignKeys = {
        @ForeignKey(
                entity = Person.class,
                parentColumns = "personId",
                childColumns = "personIdFk"
        )
    })
    public class Pet {
        String petId;
        String name;
        String personIdFk; //Foreign key to person
    }

@Entity(foreignKeys = {
            @ForeignKey(
                    entity = Person.class,
                    parentColumns = "personId",
                    childColumns = "personIdFk"
            )
    })
    public class Shoe {
        String shoeId;
        String name;
        String personIdFk; //Foreign key to person
    }


@Entity(foreignKeys = {
        @ForeignKey(
                entity = Person.class,
                parentColumns = "personId",
                childColumns = "personIdFk"
        )
    })
    public class Shirt {
            String shirtId;
            String name;
            String personIdFk; //Foreign key to person
        }
like image 972
martinomburajr Avatar asked Dec 11 '17 12:12

martinomburajr


1 Answers

Room doesn't support this directly due to some potential issues with lazy loading, but with some DAO trickery it is possible. You'll need to handle the insertions explicitly, and to query everything at once you'll need a POJO to wrap it all.

@Entity(foreignKeys = {
    @ForeignKey(
            entity = PersonEntity.class,
            parentColumns = "personId",
            childColumns = "personIdFk",
            onDelete = CASCADE
    )
})
public class Pet {
    @PrimaryKey
    private String petId;
    private String name;
    private String personIdFk;
}

@Entity(tableName = "person")
public class PersonEntity {
    @PrimaryKey
    private String personId;
}

public class Person {
    @Embedded
    private PersonEntity personEntity;
    @Relation(parentColumn = "personId", entityColumn = "personIdFk")
    private List<Pet> pets;
}

@Dao
public abstract class PersonDao {

    @Insert
    protected abstract void insert(PersonEntity personEntity);

    @Insert
    protected abstract void insert(List<Pet> pets);

    @Transaction
    public void insert(Person person) {
        insert(person.getEntity());
        insert(person.getPets());
    }

    @Query("SELECT * FROM person")
    public abstract List<Person> getAll();

}

@Database(entities = {PersonEntity.class, Pet.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {

    public abstract PersonDao personDao();

}

Constructors, getters and setters omitted for brevity.

like image 88
Thorbear Avatar answered Sep 27 '22 17:09

Thorbear