Android ROOM: при вставке новых данных я получаю ограничение FOREIGN KEY (код 787 SQLITE_CONSTRAINT_FOREIGNKEY) - PullRequest
0 голосов
/ 22 января 2020

Я знаю, что многие спрашивали об этой ошибке ограничения FOREIGN KEY (код 787 SQLITE_CONSTRAINT_FOREIGNKEY), но моя проблема немного отличается. У меня есть две сущности студент и запись. Я могу добавить студента, но когда я добавляю соответствующую запись для этого студента, я получаю эту ошибку. Сначала я добавляю данные об ученике, затем я добавляю сведения о записи ученика.

класс POJO студента

@Entity(tableName = "student_table")
public class Student {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "student_id")
    private int id;

    private String studentName;

    private String studentFatherName;

    private String studentSurname;

запись класса POJO студента

    @Entity(tableName = "newRecord_table", indices = @Index("recordId"),
            foreignKeys = @ForeignKey(entity = Student.class, parentColumns = "student_id",childColumns = "recordId",
                    onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE))

    public class NewRecord {

        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "newRecordId")
        private int id;

        public int recordId;
        public string address;
        public string mobile;

класс студента DAO

@Dao
public interface StudentDAO {

    @Insert(onConflict = REPLACE)
    void addStudent (Student student);

    @Update
    void updateStudent (Student student);

    @Delete
    void deleteStudent (Student student);

    @Query("SELECT * FROM student_table ORDER BY studentName ASC")
    LiveData<List<Student>> getAllStudents();

    @Query("DELETE FROM student_table")
    void deleteAllStudents();
}

запись класса DAO

@Dao
public interface NewRecordDAO {

    @Insert(onConflict = REPLACE)
    public void addRecord (NewRecord newRecord);

    @Update(onConflict = REPLACE)
    public void updateRecord (NewRecord newRecord);

    @Delete
    public void deleteRecord (NewRecord newRecord);

    @Query("DELETE FROM newRecord_table")
    void deleteAllRecords();

    @Query("SELECT * FROM newRecord_table ORDER BY NRdate DESC")
    LiveData<List<NewRecord>> getAllRecord();
}

класс репозитория учащихся

public class StudentRepository {
    private StudentDAO studentDAO;
    private LiveData<List<Student>> allStudents;

    public StudentRepository (Application application){
        StudentDatabase database = StudentDatabase.getInstance(application);
        studentDAO = database.studentDAO();
        allStudents = studentDAO.getAllStudents();
    }
     public void addStudent (Student student){
        new addStudentAsyncTask(studentDAO).execute(student);

     }
 public static class addStudentAsyncTask extends AsyncTask <Student,Void,Void>{
        private StudentDAO studentDAO;
        private addStudentAsyncTask (StudentDAO studentDAO){
            this.studentDAO = studentDAO;
        }
        @Override
        protected Void doInBackground(Student... students) {
            studentDAO.addStudent(students[0]);
            return null;
        }
    }

класс репозитория записей

public class NewRecordRepository {

    private NewRecordDAO newRecordDAO;
    private LiveData<List<NewRecord>> allRecords;
    private LiveData<List<NewRecord>> allRecordByStudent;

    public NewRecordRepository (Application application){
        StudentDatabase database = StudentDatabase.getInstance(application);
        newRecordDAO = database.newRecordDAO();
        allRecords = newRecordDAO.getAllRecord();

    }

    public void addRecord (NewRecord newRecord){
        new addRecordAsyncTask(newRecordDAO).execute(newRecord);
    }
 public static class addRecordAsyncTask extends AsyncTask<NewRecord,Void,Void> {
        private NewRecordDAO newRecordDAO;
        private addRecordAsyncTask (NewRecordDAO newRecordDAO){
            this.newRecordDAO = newRecordDAO;
        }
        @Override
        protected Void doInBackground(NewRecord... newRecords) {

// LOG shows: this is where it re direct me this is where the problem lies.
            newRecordDAO.addRecord(newRecords[0]);
            return null;
        }
    }

наконец, класс базы данных

@Database(entities = {Student.class, NewRecord.class}, version = 1, exportSchema = false)
public abstract class StudentDatabase extends RoomDatabase {

    private static StudentDatabase instance;

    public abstract StudentDAO studentDAO();

    public abstract NewRecordDAO newRecordDAO();

    public static synchronized StudentDatabase getInstance(Context context){
        if ( instance == null ){
            instance = Room.databaseBuilder(context.getApplicationContext(),
                    StudentDatabase.class,"students_DB")
                    .fallbackToDestructiveMigration()
                    .build();
        }
        return instance;
    }

МОЙ ЖУРНАЛ:

E / AndroidRuntime: ИСКЛЮЧИТЕЛЬНОЕ ИСКЛЮЧЕНИЕ: AsyncTask # 4 Процесс: com.timelessfusionapps.hifztasmee, PID: 12833 java .lang.RuntimeException: Произошла ошибка при выполнении doInBackground () в android .os.AsyncTask $ 3.done (AsyncTask. java: 354) в java .util.concurrent.FutureTask.finishCompletion (FutureTask. java: 383) в java .util. concurrent.FutureTask.setException (FutureTask. java: 252) в java .util.concurrent.FutureTask.run (FutureTask. java: 271) в android .os.AsyncTask $ SerialExecutor $ 1.run (AsyncTask . java: 245) в java .util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor. java: 1167) в java .util.co ncurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor. java: 641) в java .lang.Thread.run (Thread. java: 764) Причина: android .database.sqlite.SQLiteConstraintException: FOREIGN KEY ограничение не выполнено (код 787 SQLITE_CONSTRAINT_FOREIGNKEY) в android .database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId (собственный метод) в android .database.sqlite.SQLiteConnection.executeForLastInsertedRowId 7 * 10 *. 1049 в SQLiteCon. .sqlite.SQLiteSession.executeForLastInsertedRowId (SQLiteSession. java: 788) в android .database.sqlite.SQLiteStatement.executeInsert (SQLiteStatement. java: 86) в androidx.sqlite.db.framework.Site . java: 51) по адресу androidx.room.EntityInsertionAdapter.insert (EntityInsertionAdapter. java: 64) по адресу com.timelessfusionapps.hifztasmee.DOA.NewRecordDAO_Impl.addRecord (newRecordDAO_Impl. hifztasmee.Repository.NewRecordRepository $ addRecordAsyncTask.doInBackgro und (NewRecordRepository. java: 61) в com.timelessfusionapps.hifztasmee.Repository.NewRecordRepository $ addRecordAsyncTask.doInBackground (NewRecordRepository. java: 54)

1 Ответ

2 голосов
/ 22 января 2020

при вызове addRecord объекту newRecord должен быть установлен набор записей для добавленного student_id.

Если происходит сбои

    NewRecord n1 = new NewRecord();

    n1.address = "xxx";
    n1.mobile = "0000000000";
    n1.NRDate = "2020-01-01 10:30";
    newRecordRepository.addRecord(n1);

, например

Caused by: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)

чтобы дать правильную запись, вроде

    NewRecord n1 = new NewRecord();
    n1.recordId = 1;
    n1.address = "xxx";
    n1.mobile = "0000000000";
    n1.NRDate = "2020-01-01 10:30";
    newRecordRepository.addRecord(n1);

работает. 1 хорошо для показа теста, вам нужен настоящий студент, когда вы действительно

...