【问题标题】:onDelete = NO_ACTION causes error: "SQLiteConstraintException: FOREIGN KEY constraint failed" (code 787)onDelete = NO_ACTION 导致错误:“SQLiteConstraintException: FOREIGN KEY 约束失败”(代码 787)
【发布时间】:2019-11-09 06:25:14
【问题描述】:

我在 SQLite for 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;
}

当我尝试从事件表中删除记录时,我收到以下错误:

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,则不会出现问题!

我错过了什么吗?

【问题讨论】:

    标签: android sqlite android-sqlite android-room android-database


    【解决方案1】:

    如果你会看到here

    默认情况下,使用NO_ACTION

    您无需明确提供。

    @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 中删除所有指向 Event Table 行的条目 - 您正在删除。

    【讨论】:

      【解决方案2】:

      是的。 @ForeignKey 注解有助于确保条目不会进入无效状态(例如,外键不能指向不存在的条目)。

      假设您的数据库中有Event(1, "some event") 以及与会者Attendee(1, 1)。如果事件被删除,则参加者条目将进入无效状态,因为它的外键eventId 未指向有效条目。这就是为什么您会收到描述为 FOREIGN KEY constraint failed 的异常。

      onDelete = CASCADE 确保所有相关条目将与引用条目本身一起被删除:在前面描述的情况下,Attendee(1, 1) 也会在引用的事件条目 (Event(1, "some event")) 被删除时从数据库中删除。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-02
        • 1970-01-01
        • 2021-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多