In my app I have lists with Chapters, each of which contains cards. Those views of cards consist of data from a Card entity combined with data from several other tables that are joined together when pulling cards from the database. Each card can occur in none or several Chapters, so I have a many-to-many relation, which I track in an entity ChapterCardMap where each row contains the ids of one Chapter and one Card.
Now I want to display the list of all Chapters for a given value of Chapter.listId with the information of their associated cards.
For that I want use a POJO CardView that joins a subset of the information from several tables for displaying. In the DAO I have a query that successfully pulls the necessary data and put in into a single CardView for any specified cardId:
@Query("SELECT cardId, typeName, text, bookmarked FROM <JOINING data from several tables> ...")
abstract public Flow<CardView> getCardView(long cardId);
where all result columns may come from different tables. This query works when I want to pull a single CardView. But my goal is now:
I want to query a new type of POJO ChapterWithCards that has an embedded Chapter and a List<CardView> that is associated with ChapterCardMap, so I can display all the Chapters of a list with their respective cards info.
The Problem is: I can't figure out how to properly define ChapterWithCards in a way that Room knows how to load the POJO data from the database because CardView is not an entity.
Currently I have for my combined POJO:
public class ChapterWithCards {
@Embedded
private Chapter chapter; // <- this is an Entity with column 'chapterId'
@Relation(
parentColumn = "chapterId",
entityColumn = "cardId",
associateBy = @Junction(ChapterCardMap.class)
)
private List<CardView> cardViews; // <- this is NOT an Entity but a POJO with field 'cardId'
public Chapter getChapter() { return chapter; }
public void setChapter(Chapter chapter) { this.chapter = chapter; }
public List<CardView> getCardViews() { return cardViews; }
public void setCardViews(List<CardView> cardViews) { this.cardViews = cardViews; }
}
The where Chapters are defined as an entity:
@Entity
public class Chapter {
@PrimaryKey(autoGenerate = true)
public long chapterId;
private long listId;
private String chapterTitle;
public CardListChapter(long listId, String chapterTitle){
this.listId = listId;
this.chapterTitle = chapterTitle;
}
public long getChapterId() { return chapterId; }
public long getListId() { return listId; }
public void setListId(long listId) { this.listId = listId; }
public String getChapterTitle() { return chapterTitle; }
public void setChapterTitle(String title) { this.chapterTitle = title; }
}
The mappings for the Junction are defined as an entity, too:
@Entity(primaryKeys = {"chapterId", "cardId"})
public class ChapterCardMap {
private long chapterId;
private long cardId;
public CardListChapterMap(long chapterId, long cardId){
this.chapterId = chapterId;
this.cardListId = cardListId;
}
public long getCardListId() { return cardListId; }
public void setCardListId(long cardListId) { this.cardListId = cardListId; }
public long getCardId() { return cardId; }
public void setCardId(long cardId) { this.cardId = cardId; }
}
And the CardView POJO is defined as:
public class CardView {
@ColumnInfo(name = "cardId")
public Long cardId;
@ColumnInfo(name = "typeName")
public String typeName;
@ColumnInfo(name = "text")
public String text;
@ColumnInfo(name = "bookmarked")
public boolean bookmarked;
public FlashcardView(Long cardId, String typeName, String text, boolean bookmarked){
this.cardId = cardId;
this.typeName = typeName;
this.text = text;
this.bookmarked = bookmarked;
}
public Long getCardId() { return cardId; }
public String getTypeName() { return typeName; }
public String getText() { return text; }
public boolean getBookmarked() { return bookmarked; }
}
When I compile the code, its says for CardView:
error: The class must be either @Entity or @DatabaseView.
But I don't want CardView to be an entity, because it contains information that combines different objects, e.g. typeName is a column from a table Type where the name is pulled by referencing a typeId in the Card table. Those are just different objects and should not be in the same table, i.e. the same entity. Still, I need to display the card type and don't want to make another database request for each card that I show, so I am using JOINs and a POJO.
Also I cannot make CardView a DatabaseView, because then I cannot specify the value of Chapter.listId that should be pulled from the database.
My question is then, how do I have to define ChapterWithCards so that I have Room pull the all the data for me in a structured way so I can access it easily? Do I have to define a certain getter in my DAO?
Thanks!
You use @Ignore annotation e.g.
Then you will need some means of populating the CardView List from wherever, it is impossible to say from where as insufficient information has been provided.
If so then you either have an @Relation or you build the list. Again impossible to say more.