Search code examples
androidandroid-room

Is it possible to create a table in the Room without a primary key?


I have a table in MySql and I named it FAQs and inside the table, There are two columns, Question column and Answer column, I want to get the data who inside the FAQs table and store it in the offline database but I got this message An entity must have at least 1 field annotated with @PrimaryKey

The Table

@Entity(tableName = "FAQs")
public class FAQModel {
    
    private String question, answer;

    public String getQuestion() {
        return question;
    }

    public String getAnswer() {
        return answer;
    }

}

Is it possible to create a table in the Room without a primary key?


Solution

  • Yes you can, with some difficulty, but not via room annotation, and even still it would have a primary key so really the answer is No.

    • It is possible (e.g. via a callback) to create a table that does not appear to have a primary key column e.g. CREATE TABLE IF NOT EXISTS the_table (question TEXT, answer TEXT). However,
      • it would have a primary key on the column rowid which is normally hidden.
      • such a table would not be able to be readily used, as you would have to avoid Room's compilation time SQL statement checking.
      • you could also not take direct advantage of Room's underlying table to/from object handling.

    However, you make the comment

    But in the android app I only get the question and answer column and I am not getting faqId because I don't want to use it inside my app.

    So you could have a POJO class that excludes the faqId column e.g.

    class FAQModelLessIdColumn {
        String question,answer;
    }
    

    Assuming that FAQModel is the entity and thus the tablename then with the above you could have an @Query such as:-

    @Query("SELECT * FROM faqmodel")
    abstract List<FAQModelLessIdColumn> getFAQModelsLessTheFaqIdColumn();
    

    However, over time, you will probably learn that the primary key column, is highly beneficial as it MUST uniquely identify a single row in the table. So from a single value you can perform CRUD operations efficiently.

    • As an analogy consider the table as a list where the questions have been written down in no particular order. To find a question and it's answer How many days in a leap year then you would have to search the entire list until you found the question. If however the list was split into lists according to the first character of the question and these were maintained in order then by skipping to the H list would likely make finding the question easier. Thus indexes can greatly reduce search times. So having the faqId available enables searches via the primary index and they will be faster.