【问题标题】:Android ROOM: When Inseting new data I get FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)Android ROOM:插入新数据时出现 FOREIGN KEY 约束失败(代码 787 SQLITE_CONSTRAINT FOREIGN KEY)
【发布时间】:2020-01-22 13:21:57
【问题描述】:

我知道很多人都询问过这个 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.concurrent.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(Native 方法) 在 android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796) 在 android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788) 在 android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86) 在 androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51) 在 androidx.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:64) 在 com.timelessfusionapps.hifztasmee.DOA.NewRecordDAO_Impl.addRecord(NewRecordDAO_Impl.java:242) 在 com.timelessfusionapps.hifztasmee.Repository.NewRecordRepository$addRecordAsyncTask.doInBackground(NewRecordRepository.java:61) 在 com.timelessfusionapps.hifztasmee.Repository.NewRecordRepository$addRecordAsyncTask.doInBackground(NewRecordRepository.java:54)

【问题讨论】:

    标签: android foreign-keys android-room


    【解决方案1】:

    在调用addRecordnewRecord 对象时需要为添加的student_id 设置recordid。

    如果有

        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)
    

    更改以提供适当的 recordId,例如

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

    工作。 1 可以展示测试,你需要合适的学生做真正的

    【讨论】:

    • 我明白你想说什么,但是我必须在哪里实现这个逻辑,当我在我的添加记录活动中实现这个逻辑时,它仍然给我同样的错误,当我添加这个逻辑时在存储库类中,回收器视图未显示任何数据
    • @sulli110 在调用 addRecord 时让正确的学生通过非常重要,如何在您提供的代码中看不到
    • 我从studentviewmodel.getallstudents.getvalue.get(position).getId()得到了ID值;这就是我获得 id 的方式,现在它正在工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多