Search code examples
javaandroidsqliteforeign-keys

How can I fix a Foreign FOREIGN KEY constraint failed (code 787) error that doesn't have a Constraint?


Problem: I'm receiving a FOREIGN CONSTRAINT error (code 787) when I try to delete a file stored in a SQLite database. Everything else works with adding (i.e., insert) the files and even reading (opening) them. I just can't delete them.

What I have tried: I've read 4-5 posts calling it a known issue. I think one post involved a type of conflict. A type conflict might be a possibility except I can insert and read (open) just fine. I don't think that is the issue in my case... maybe, but I'm not sure. Before going that far I thought I would post here. I'm still learning about Android Room and Android in general, but could use some insights by those more learned than me.

Where the error occurs

rdb.getFilesDao().deleteFile(bFile);

Files.java (Entity)

@Entity(tableName = "Files")
public class Files implements Parcelable {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "FileID")
    private int fileID;

    @ColumnInfo(name = "FileName")
    private String fileName;

    @TypeConverters(FileTypeConverter.class)
    @ColumnInfo(name = "FileData", typeAffinity = ColumnInfo.TEXT)
    private byte[] fileData;

    @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH)
    public Files(int fileID, String fileName, byte[] fileData){
        this.fileID = fileID;
        this.fileName = fileName;
        this.fileData = fileData;
    }

    public Files(Parcel in){
        this.fileID = in.readInt();
        this.fileName = in.readString();
        this.fileData = in.createByteArray();
    }

    public static final Creator<Files> CREATOR = new Creator<Files>() {
        @Override
        public Files createFromParcel(Parcel in) {
            return new Files(in);
        }

        @Override
        public Files[] newArray(int size) {
            return new Files[size];
        }
    };

FilesDao.java (Dao)

    @Dao
    public interface FilesDao {
        @Insert
        long addFile(Files file);
        @Update
        void updateFile(Files file);
        @Delete
        void deleteFile(Files file);
    
        @Query("SELECT * FROM Files")
        List<Files> getFiles();
        @Query("SELECT * FROM Files WHERE FileID = :fileID")
        Files getFile(int fileID);
    }

Files Structure (json)

    "tableName": "Files",
    "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`FileID` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `FileName` TEXT, `FileData` TEXT)",
    "fields": [
      {
        "fieldPath": "fileID",
        "columnName": "FileID",
        "affinity": "INTEGER",
        "notNull": true
      },
      {
        "fieldPath": "fileName",
        "columnName": "FileName",
        "affinity": "TEXT",
        "notNull": false
      },
      {
        "fieldPath": "fileData",
        "columnName": "FileData",
        "affinity": "TEXT",
        "notNull": false
      }
    ],
    "primaryKey": {
      "columnNames": [
        "FileID"
      ],
      "autoGenerate": true
    },
    "indices": [],
    "foreignKeys": []
  },

Updated to add pics to assist comment/questions:

Structure

Constraint


Solution

  • With the help and comments of Susan Mustafa, I simply had my join table dependency in the wrong code order when attempting to delete the file. Once I reversed the order of the code pertaining to the file the Foreign Key error disappeared. I should have caught this but didn't, the foreign key dependencies should be removed first before removing the primary.

    These were in reverse order:

    rdb.getFilesByNoteDao().delete(new FilesByNote(id, oFile.getFileID()));
    rdb.getFilesDao().deleteFile(oFile);