当前位置: 首页 > 知识库问答 >
问题:

Android ROOM:当输入新数据时,我得到FOREIGN KEY约束失败(代码787SQLITE_CONSTRAINT_FOREIGNKEY)

阴礼骞
2023-03-14

我知道很多人问过这个外键约束失败(代码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
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
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。永恒的融合。hifztasmee,PID:12833 java。lang.RuntimeException:在android上执行doInBackground()时出错。操作系统。3美元。在java上完成(AsyncTask.java:354)。util。同时发生的未来任务。在java完成(FutureTask.java:383)。util。同时发生的未来任务。java上的setException(FutureTask.java:252)。util。同时发生的未来任务。在android上运行(FutureTask.java:271)。操作系统。AsyncTask$SerialExecutor$1。在java上运行(AsyncTask.java:245)。util。同时发生的线程池执行器。java上的runWorker(ThreadPoolExecutor.java:1167)。util。同时发生的ThreadPoolExecutor$Worker。在java上运行(ThreadPoolExecutor.java:641)。朗。丝线。运行(Thread.java:764)的原因是:android。数据库sqlite。SQLiteConstraintException:android上的外键约束失败(代码787 SQLITE_constraint_FOREIGNKEY)。数据库sqlite。SQLiteConnection。android上的nativeExecuteForLastInsertedRowId(本机方法)。数据库sqlite。SQLiteConnection。android上的executeForLastInsertedRowId(SQLiteConnection.java:796)。数据库sqlite。SQLiteSession。android上的executeForLastInsertedRowId(SQLiteSession.java:788)。数据库sqlite。SQLITE声明。androidx上的executeInsert(SQLiteStatement.java:86)。sqlite。db。框架FrameworkSQLiteStatement。androidx上的executeInsert(FrameworkSQLiteStatement.java:51)。房间EntityInsertionAdapter。在com上插入(EntityInsertionAdapter.java:64)。永恒的融合。你好。多阿。新记录。addRecord(NewRecordDAO_Impl.java:242)位于com。永恒的融合。你好。存储库。NewRecordRepository$addRecordAsyncTask。doInBackground(NewRecordRepository.java:61)位于com。永恒的融合。你好。存储库。NewRecordRepository$addRecordAsyncTask。doInBackground(NewRecordRepository.java:54)

共有1个答案

公孙弘深
2023-03-14

调用addRecordnewRecord对象时,需要为已添加的学生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可以显示测试,你需要适当的学生当做真正的

 类似资料:
  • 我在Amazon RDS上的mysql DB8.0.20版本中有两个表,它们之间有一个外键。 当我尝试插入第二个表时,我得到一个外键错误,但我确定第一个表中存在该键。 然后我跑: 那么,如果ID存在于表1中,为什么表2不能在外键列中使用它呢?我错过了什么?

  • 问题内容: 我想在AndroidRoom中用两个外键创建一个数据库。每次我尝试在数据库中插入曲目时,程序都会崩溃,并说“外键costraint失败(代码787)”。也许你们中的某人知道原因,可以为我提供帮助。 道道 “ Kategorie”和“ Playlist”也是数据库中的表。 卡特戈里 问题答案: 你需要有表中的行,并用相同的外键为具有要插入。

  • 问题内容: 我试图在表中插入值。但是只插入一个值。尝试插入新值时,日志猫出现错误。 日志猫显示: 插入行时,这两行显示错误。 EventTableHelper 如何解决呢? 问题答案: 您的代码可能违反了字段上主键的唯一性约束。 两种可能的解决方案是: 确保您为每个对象返回唯一值。现在,我看不到您将任何标识符传递给其构造函数,并且可能所有事件都以相同的值插入。 如果您不希望自己生成ID,则可以将设

  • 我不熟悉Android房间。我正在学习它,所以我尝试开发一个演示应用程序类名:,它有,,,地址类对象,父类对象//Getter和Setter 我编写了一些代码,但出现错误: 外键约束失败 我尝试了堆栈溢出中给出的解决方案,但仍然得到了错误。请帮忙! 主要活动。JAVA AppDatabase。班 公共抽象类AppDatabase扩展了RoomDatabase{ } 地址1。班 父母1。班

  • 问题内容: 我收到此错误消息: 第40行的错误1217(23000):无法删除或更新父行:外键约束失败 …当我尝试放置桌子时: …定义如下: 有趣的是, 我已经删除 了模式中具有外键的 所有其他表。实际上,除了表外,数据库是空的。 如果数据库中没有其他对象,怎么可能会有子行?据我所知,InnoDB不允许在其他模式上使用外键,对吗? (我什至可以运行命令:-?) 问题答案: 两种可能性: 在另一个架

  • 嗨,我知道有人问过这个问题,但我还没有找到正确的答案,为什么当我尝试做我的第二个插入: 我得到了错误: 错误1452(23000):无法添加或更新子行:外键约束失败(.,约束外键()引用()) 下面的DDL代码: