onDelete = NO_ACTION causes error: "SQLiteConstraintException: FOREIGN KEY constraint failed" (code 787)
onDelete = NO_ACTION causes error: "SQLiteConstraintException: FOREIGN KEY constraint failed" (code 787)
我在 SQLite 上为 Android 使用 Room,我有以下两个 Pojo 实体:
@Entity
public class Event {
@PrimaryKey
@NonNull
private String eventId;
private String eventName;
}
@Entity(primaryKeys = {"eventId","attendeeId"},
foreignKeys = {
@ForeignKey(entity = Event.class,
parentColumns = "eventId",
childColumns = "eventId" ,onDelete = NO_ACTION)
})
public class Attendee {
@NonNull
private String eventId;
@NonNull
private String attendeeId;
}
当我尝试从事件 table 中删除一条记录时,出现以下错误:
Caused by: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787) at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:732)
at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45)
at com.minapharm.hixspro.POJO.Room.Events.EventDao_Impl.deleteTable(EventDao_Impl.java:168)
但是,如果我将 onDelete 更改为 CASCADE,则不会出现任何问题!
我是不是漏掉了什么?
是的。 @ForeignKey
注释有助于确保条目不会进入无效状态(例如,外键不能指向不存在的条目)。
假设您的数据库中有 Event(1, "some event")
以及一名与会者 Attendee(1, 1)
。如果事件被删除,则与会者条目将进入无效状态,因为它的外键 eventId
未指向有效条目。这就是为什么您会收到描述为 FOREIGN KEY constraint failed
.
的异常的原因
onDelete = CASCADE
确保所有相关条目都将与引用的条目本身一起删除:在前面描述的情况下,当引用的事件条目 (Event(1, "some event")
) 被删除。
如果你会看到 here。
By default, NO_ACTION
is used.
您无需明确提供。
@Entity(primaryKeys = {"eventId","attendeeId"},
foreignKeys = {
@ForeignKey(entity = Event.class,
parentColumns = "eventId",
childColumns = "eventId")
})
public class Attendee {
@NonNull
private String eventId;
@NonNull
private String attendeeId;
}
此外,您需要了解数据库是一次性创建的。您应该重新安装应用程序,然后检查删除是否有效。
已编辑: 由于您定义了 ForeignKey 而不是 onDelete CASCADE,因此您必须从 Attendee 中手动删除所有指向事件 Table 行的条目- 你正在删除。
我在 SQLite 上为 Android 使用 Room,我有以下两个 Pojo 实体:
@Entity
public class Event {
@PrimaryKey
@NonNull
private String eventId;
private String eventName;
}
@Entity(primaryKeys = {"eventId","attendeeId"},
foreignKeys = {
@ForeignKey(entity = Event.class,
parentColumns = "eventId",
childColumns = "eventId" ,onDelete = NO_ACTION)
})
public class Attendee {
@NonNull
private String eventId;
@NonNull
private String attendeeId;
}
当我尝试从事件 table 中删除一条记录时,出现以下错误:
Caused by: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787) at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:732)
at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45)
at com.minapharm.hixspro.POJO.Room.Events.EventDao_Impl.deleteTable(EventDao_Impl.java:168)
但是,如果我将 onDelete 更改为 CASCADE,则不会出现任何问题!
我是不是漏掉了什么?
是的。 @ForeignKey
注释有助于确保条目不会进入无效状态(例如,外键不能指向不存在的条目)。
假设您的数据库中有 Event(1, "some event")
以及一名与会者 Attendee(1, 1)
。如果事件被删除,则与会者条目将进入无效状态,因为它的外键 eventId
未指向有效条目。这就是为什么您会收到描述为 FOREIGN KEY constraint failed
.
onDelete = CASCADE
确保所有相关条目都将与引用的条目本身一起删除:在前面描述的情况下,当引用的事件条目 (Event(1, "some event")
) 被删除。
如果你会看到 here。
By default,
NO_ACTION
is used.
您无需明确提供。
@Entity(primaryKeys = {"eventId","attendeeId"},
foreignKeys = {
@ForeignKey(entity = Event.class,
parentColumns = "eventId",
childColumns = "eventId")
})
public class Attendee {
@NonNull
private String eventId;
@NonNull
private String attendeeId;
}
此外,您需要了解数据库是一次性创建的。您应该重新安装应用程序,然后检查删除是否有效。
已编辑: 由于您定义了 ForeignKey 而不是 onDelete CASCADE,因此您必须从 Attendee 中手动删除所有指向事件 Table 行的条目- 你正在删除。