onDelete = NO_ACTION вызывает ошибку: «SQLiteConstraintException: ограничение FOREIGN KEY не выполнено» (код 787) - PullRequest
0 голосов
/ 27 июня 2019

Я использую Room поверх SQLite для Android, и у меня есть следующие две сущности 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, никаких проблем не возникает!

Я что-то упустил?

Ответы [ 2 ]

1 голос
/ 27 июня 2019

Если вы увидите здесь .

По умолчанию используется 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, которые указывают на строку таблицы событий - вы удаляете.

1 голос
/ 27 июня 2019

Да.@ForeignKey аннотация помогает гарантировать, что запись не может войти в недопустимое состояние (например, внешний ключ не может указывать на несуществующую запись).

Представьте, что у вас есть Event(1, "some event") вваша база данных, а также посетитель Attendee(1, 1).Если событие удалено, то запись участника перейдет в недопустимое состояние, поскольку его внешний ключ eventId не указывает на допустимую запись.Вот почему вы получаете исключение с описанием FOREIGN KEY constraint failed.

onDelete = CASCADE гарантирует, что все зависимые записи будут удалены самой ссылочной записью: в описанном ранее случае Attendee(1, 1) также будет удален избаза данных при удалении указанной записи события (Event(1, "some event")).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...