具有一对一关系外键约束的房间数据库失败错误
Room database with one-to-one relation foreign key constraint failed error
我有一个包含两个 table 学生和课程的数据库。我可以在 Student table 中插入数据,但是当我尝试将数据插入 Course table 时,应用程序崩溃了。这是 logcat:
2019-01-21 19:56:22.302 28939-29121/? E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.rodroiddev.catalogulinstructoruluiauto, PID: 28939
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:353)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:50)
at android.arch.persistence.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.java:114)
at com.rodroiddev.catalogulinstructoruluiauto.db.CourseDao_Impl.insert(CourseDao_Impl.java:104)
at com.rodroiddev.catalogulinstructoruluiauto.course.CourseRepository$InsertCourseAsyncTask.doInBackground(CourseRepository.java:53)
at com.rodroiddev.catalogulinstructoruluiauto.course.CourseRepository$InsertCourseAsyncTask.doInBackground(CourseRepository.java:44)
at android.os.AsyncTask.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
插入代码如下:
private static class InsertCourseAsyncTask extends AsyncTask<Course, Void, Void> {
private CourseDao courseDao;
public InsertCourseAsyncTask(CourseDao courseDao) {
this.courseDao = courseDao;
}
@Override
protected Void doInBackground(Course... courses) {
courseDao.insert(courses[0]);
return null;
}
}
Course.java
@Entity(tableName = "course_table",
foreignKeys = @ForeignKey(entity = Student.class,
parentColumns = "sId",
childColumns = "studentId",
onDelete = CASCADE),
indices = {@Index("studentId")})
public class课程{
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "cId")
public int id;
public String kmStart;
public String kmStop;
@ColumnInfo(name = "studentId")
public int studentId;
public Course(String kmStart, String kmStop) {
this.kmStart = kmStart;
this.kmStop = kmStop;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getKmStart() {
return kmStart;
}
public String getKmStop() {
return kmStop;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public int getStudentId() {
return studentId;
}
}
CourseDao
@Dao
public 界面 CourseDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(Course... courses);
@Update(onConflict = OnConflictStrategy.IGNORE)
void update(Course course);
@Delete
void delete(Course course);
@Query("DELETE FROM course_table")
void deleteAllCourses();
@Query("SELECT * FROM course_table ORDER BY kmStart ASC")
LiveData<List<Course>> getAllCourses();
}
我希望你能根据我在这里发布的信息帮助我。
谢谢!
保存前是否将studentId设置为course对象?如果你不这样做,它会崩溃,因为它会尝试为 studentId 添加 0 作为不存在的外键值。
设置Course对象的studentId为Student对象的id。并先保存 Student 以便它可以获得一个 id
我有一个包含两个 table 学生和课程的数据库。我可以在 Student table 中插入数据,但是当我尝试将数据插入 Course table 时,应用程序崩溃了。这是 logcat:
2019-01-21 19:56:22.302 28939-29121/? E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.rodroiddev.catalogulinstructoruluiauto, PID: 28939
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:353)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:50)
at android.arch.persistence.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.java:114)
at com.rodroiddev.catalogulinstructoruluiauto.db.CourseDao_Impl.insert(CourseDao_Impl.java:104)
at com.rodroiddev.catalogulinstructoruluiauto.course.CourseRepository$InsertCourseAsyncTask.doInBackground(CourseRepository.java:53)
at com.rodroiddev.catalogulinstructoruluiauto.course.CourseRepository$InsertCourseAsyncTask.doInBackground(CourseRepository.java:44)
at android.os.AsyncTask.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
插入代码如下:
private static class InsertCourseAsyncTask extends AsyncTask<Course, Void, Void> {
private CourseDao courseDao;
public InsertCourseAsyncTask(CourseDao courseDao) {
this.courseDao = courseDao;
}
@Override
protected Void doInBackground(Course... courses) {
courseDao.insert(courses[0]);
return null;
}
}
Course.java
@Entity(tableName = "course_table",
foreignKeys = @ForeignKey(entity = Student.class,
parentColumns = "sId",
childColumns = "studentId",
onDelete = CASCADE),
indices = {@Index("studentId")})
public class课程{
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "cId")
public int id;
public String kmStart;
public String kmStop;
@ColumnInfo(name = "studentId")
public int studentId;
public Course(String kmStart, String kmStop) {
this.kmStart = kmStart;
this.kmStop = kmStop;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getKmStart() {
return kmStart;
}
public String getKmStop() {
return kmStop;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public int getStudentId() {
return studentId;
}
}
CourseDao
@Dao
public 界面 CourseDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(Course... courses);
@Update(onConflict = OnConflictStrategy.IGNORE)
void update(Course course);
@Delete
void delete(Course course);
@Query("DELETE FROM course_table")
void deleteAllCourses();
@Query("SELECT * FROM course_table ORDER BY kmStart ASC")
LiveData<List<Course>> getAllCourses();
}
我希望你能根据我在这里发布的信息帮助我。 谢谢!
保存前是否将studentId设置为course对象?如果你不这样做,它会崩溃,因为它会尝试为 studentId 添加 0 作为不存在的外键值。
设置Course对象的studentId为Student对象的id。并先保存 Student 以便它可以获得一个 id