Search code examples
androidandroid-sqliteandroid-room

How do I perform a Room DAO multi table join @Query using select fields?


My Problem: I'm struggling to eliminate the compiling error on the following Room @Query statement in a Room DAO. As you can see, the SQLite query statement is joining various fields from different tables. The missing fields identified by the error are a part of the Notes class constructor identified in the List type for the method. I think I need to change the List type identified. If I'm right, I need some guidance/suggestion on how I should resolve it. Do I need to create a new Class and DAO with just those specific fields queried? Or maybe just a class since there is not table specific to these fields only. The error is:

error: The columns returned by the query does not have the fields [commentID,questionID,quoteID,termID,topicID,deleted] in com.mistywillow.researchdb.database.entities.Notes even though they are annotated as non-null or primitive. Columns returned by the query: [NoteID,SourceID,SourceType,Title,Summary] List getNotesOnTopic(String topic);

@Query("SELECT n.NoteID, s.SourceID, s.SourceType, s.Title, c.Summary FROM Comments as c " +
        "LEFT JOIN Notes as n ON n.CommentID = c.CommentID " +
        "LEFT JOIN Sources as s ON n.SourceID = s.SourceID " +
        "LEFT JOIN Topics as t ON n.TopicID = t.TopicID WHERE t.Topic = :topic AND n.Deleted = 0")
List<Notes> getNotesOnTopic(String topic);

What I'm trying to do: I'm attempting to convert and existing Java desktop app with an embedded an SQLite database. The above query does work fine in that app. I only want to pass field data from these tables.

What I've tried: I've done some googling and visited some forums for the last few days (e.g. Android Forum, Developer.Android.com) but most of the Room @Query examples are single table full field queries (e.g. "Select * From table"). Nothing I found yet (there is probably something) quite addresses how and what to do if you are joining and querying only specific fields across tables.


Solution

  • I think I may have fixed my issue. I just created a new class called SourceTable and designated the queried fields in the constructor. The only catch was I, according to a follow up error, was that the parameters had to match the field names.

    public class SourcesTable {
        private int NoteID;
        private int SourceID;
        private String SourceType;
        private String Title;
        private String Summary;
    
        public SourcesTable(int NoteID, int SourceID, String SourceType, String Title, String Summary){
            this.NoteID = NoteID;
            this.SourceID = SourceID;
            this.SourceType = SourceType;
            this.Title = Title;
            this.Summary = Summary;
        }
    }
    

    and then I update my list method:

    List<SourcesTable> getNotesOnTopic(String topic);