how to add prefix in roomDatabase?

643 Views Asked by At

I have a problem in my roomDatabase.

I searched on google and found some solutions but I can't solve my problem.

Can anyone help me?

Note : I want to use Object Oriented in my project.

Error :

Multiple fields have the same columnName: class_id. Field names: classId, classId.

ClassEntry :

@Entity(tableName = "class")

public class ClassEntry {

@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = COLUMN_CLASS_ID)
private int classId;

@ColumnInfo(name = "name")
private String className;
@ColumnInfo(name = "day")
private String classDay;

public ClassEntry(int classId, String className, String classDay) {
    this.classId = classId;
    this.className = className;
    this.classDay = classDay;
}

@Ignore
public ClassEntry(int classId) {
    this.classId = classId;
}

StudentEntry :

@Entity(tableName = "student",
    primaryKeys = {COLUMN_CLASS_ID, COLUMN_STUDENT_ID},
    foreignKeys = {@ForeignKey(
            entity = ClassEntry.class,
            parentColumns = COLUMN_CLASS_ID,
            childColumns = COLUMN_CLASS_ID,
            onDelete = CASCADE)})
public class StudentEntry extends ClassEntry{

@ColumnInfo(name = COLUMN_CLASS_ID)
private int classId;
@NonNull
@ColumnInfo(name = COLUMN_STUDENT_ID)
private String studentId;
@ColumnInfo(name = "first_name")
private String firstName;
@ColumnInfo(name = "last_name")
private String lastName;

public StudentEntry(int classId, @NotNull String studentId, String firstName, String lastName) {
    super(classId);
    this.studentId = studentId;
    this.firstName = firstName;
    this.lastName = lastName;
}
1

There are 1 best solutions below

0
MikeT On BEST ANSWER

Your issue is that you are extending the StudentEntry class with the ClassEntry class. This is not how you manage related data with Room. You are effectively saying you want a table inside. Rather as you want a one (class) to many (students) relationship.

As such you want an Object that will contain a ClassEntry and the respective StudentEntries (0 or more). For this you create a normal POJO class embedding the Parent table and relating the child class(es).

So your ClassEntry class is fine as it is. However your StudentEntry class could be :-

@Entity(tableName = "student",
        primaryKeys = {COLUMN_CLASS_ID, COLUMN_STUDENT_ID},
        foreignKeys = {@ForeignKey(
                entity = ClassEntry.class,
                parentColumns = COLUMN_CLASS_ID,
                childColumns = COLUMN_CLASS_ID,
                onDelete = CASCADE)})
public class StudentEntry /* extends ClassEntry <<<<<<<<<< COMMENTED OUT */ {

    @ColumnInfo(name = COLUMN_CLASS_ID)
    private int classId;
    @NonNull
    @ColumnInfo(name = COLUMN_STUDENT_ID)
    private String studentId;
    @ColumnInfo(name = "first_name")
    private String firstName;
    @ColumnInfo(name = "last_name")
    private String lastName;

    public StudentEntry(int classId, @NonNull String studentId, String firstName, String lastName) {
        /* super(classId); <<<<<<<<<< COMMENTED OUT */
        this.classId = classId; //<<<<<<<<<< ADDED
        this.studentId = studentId;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @NonNull
    public String getStudentId() {
        return studentId;
    }

    public void setStudentId(@NonNull String studentId) {
        this.studentId = studentId;
    }

    public int getClassId() {
        return classId;
    }

    public void setClassId(int classId) {
        this.classId = classId;
    }
}
  • i.e. it doesn't extend the ClassEntry and therefore doesn't call the Class Entry super. see comments.
  • note redundant getters and setters removed

Then you add another POJO class such as :-

class ClassEntryWithStudentEntrys {

    @Embedded
    ClassEntry classEntry;
    @Relation(entity = StudentEntry.class,parentColumn = COLUMN_CLASS_ID,entityColumn = COLUMN_CLASS_ID)
    List<StudentEntry> studentEntryList;
}
  • @Embedded includes the following class
  • @Relation defines the relationship

The Dao's could be :-

@Dao
interface AllDao {

    @Insert
    long insert(ClassEntry classEntry);
    @Insert
    long insert(StudentEntry studentEntry);
    @Transaction
    @Query("SELECT * FROM class")
    List<ClassEntryWithStudentEntrys> getAllClassEntriesWithStudentEntries();

}
  • the Last one utilising the POJO with the Embedded and Relation annotations.

Working Example using the above

Consider the following code, this adds 2 Classes Class1 and Class2. Class1 has 2 students added, Class 2 has 3 students added. Finally the ClassEntriesWithStudnetEntries are extracted using the getAllClassEntriesWithStudentEntries Query:-

    dao = db.getAllDao();

    long class1 = dao.insert(new ClassEntry(0,"Class1","Mon"));
    dao.insert(new StudentEntry((int)class1,"student1","Mary","Smith"));
    dao.insert(new StudentEntry((int) class1,"student2","Fred","Bloggs"));
    long class2 = dao.insert(new ClassEntry(0,"Class2","Tue"));
    dao.insert(new StudentEntry((int) class2,"student3","Sarah","Tomms"));
    dao.insert(new StudentEntry((int)class2,"student4","Alan","Richardson"));
    dao.insert(new StudentEntry((int)class2,"student5","Jayne","Lockyer"));

    List<ClassEntryWithStudentEntrys> classWithStudentsList = dao.getAllClassEntriesWithStudentEntries();
    for (ClassEntryWithStudentEntrys c: classWithStudentsList) {
        Log.d("CLASSSTUDENTINFO","Class is " + c.classEntry.getClassName() + " on Day " + c.classEntry.getClassDay() + " ID is " + c.classEntry.getClassId());
        for (StudentEntry s: c.studentEntryList) {
            Log.d("CLASSSTUDENTINFO","\tStudent is " + s.getFirstName() + "," + s.getLastName() + " Student ID is " + s.getStudentId());
        }
    }

Result as output to the log

D/CLASSSTUDENTINFO: Class is Class1 on Day Mon ID is 1
D/CLASSSTUDENTINFO:     Student is Mary,Smith Student ID is student1
D/CLASSSTUDENTINFO:     Student is Fred,Bloggs Student ID is student2
D/CLASSSTUDENTINFO: Class is Class2 on Day Tue ID is 2
D/CLASSSTUDENTINFO:     Student is Sarah,Tomms Student ID is student3
D/CLASSSTUDENTINFO:     Student is Alan,Richardson Student ID is student4
D/CLASSSTUDENTINFO:     Student is Jayne,Lockyer Student ID is student5
  • Note the above is just a demo, it is not intended to be rerun.