Android Room FOREIGN KEY 约束失败(代码 787)

Posted

技术标签:

【中文标题】Android Room FOREIGN KEY 约束失败(代码 787)【英文标题】:Android Room FOREIGN KEY constraint failed (code 787) 【发布时间】:2018-06-06 21:01:59 【问题描述】:

我想用两个外键在 android Room 中创建一个数据库。每次我尝试将曲目插入数据库时​​,程序都会崩溃并说“外键 costraint 失败(代码 787)”。也许你们当中有人知道原因并可以帮助我。

@Entity(foreignKeys = @ForeignKey(
    entity = Kategorie.class,
    childColumns = "kategorieFremdschluessel",
    parentColumns = "kategorieID",
    onUpdate = ForeignKey.CASCADE,
    onDelete = ForeignKey.CASCADE
    ),
    @ForeignKey(
            entity = Playlist.class,
            childColumns = "playlistFremdschluessel",
            parentColumns = "uuid",
            onUpdate = ForeignKey.CASCADE,
            onDelete = ForeignKey.CASCADE
    )
 )

public class Track 

@PrimaryKey(autoGenerate = true)
private int uid;

private String trackTitel;
private String playlistName;
private String jsonObjectString;
private int kategorieFremdschluessel;
private int playlistFremdschluessel;

@Ignore
public Track(String trackTitel, String playlistName, String jsonObjectString) 
    this.trackTitel = trackTitel;
    this.playlistName = playlistName;
    this.jsonObjectString = jsonObjectString;


public Track(String trackTitel, String jsonObjectString) 
    this.trackTitel = trackTitel;
    this.jsonObjectString = jsonObjectString;

//Getter and Setter

@Dao

TrackDao

public interface TrackDao 

@Query("SELECT * FROM Track WHERE playlistName LIKE :playlist")
List<Track> getAllTracks(String playlist);

@Query("SELECT * FROM Track WHERE kategorieFremdschluessel = :kategorieFremdschluessel")
List<Track> loadAllKategorieTracks(int kategorieFremdschluessel);

@Query("SELECT * FROM Track WHERE playlistFremdschluessel = :playlistFremdschluessel")
List<Track> loadAllPlaylistTracks(int playlistFremdschluessel);

@Insert
void insertAll(List<Track> trackList);

@Insert
void insertOne(Track track);

@Update
void updateOne(Track track);

@Delete
void delete(Track track);

“类别”和“播放列表”也是数据库中的表。

@Entity
public class Playlist


@PrimaryKey(autoGenerate = true)
private int uuid;

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

类别

@Entity
public class Kategorie 



@PrimaryKey(autoGenerate = true)
private int kategorieID;


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

【问题讨论】:

您在类别和播放列表表中是否有 uid 与您要插入的曲目的 uid 相同的行? @ElectroWeak 是的,两个类都有一个 PrimaryKey。类别 = "kategorieID" 和播放列表 = "uuid" 。所以名字是一样的。 不,我的意思是你需要在表Kategorie和Playlist中有一行具有相同的主键,这也与你正在插入的Track的主键相同。 也就是说,如果类别和播放列表中没有具有相同外键的对应行,则无法将曲目插入数据库。有关外键的更多信息here 是的,如果您将Track的外键设置为null,您可以添加Track,然后用ID更新它,但是您需要将kategorieFremdschluessel从类型int更改为Integer,因为否则,Room 会生成 NOT NULL 列,这会禁止表中的空值。 【参考方案1】:

出现这个错误还有另一个原因,它占用了我很多时间,因为互联网上所有可能的解决方案在我看来都是徒劳的。

如果使用父表的rowId作为parentColumn键,则不能使用外键约束。

根据SQLite documentation on Foreign Keys:

父键是父表中的列或列集 外键约束所指的。这通常是,但不是 始终是父表的主键。父键必须是 父表中的一个或多个命名列,不是 rowid。

【讨论】:

【参考方案2】:

您需要在表KategoriePlaylist 中拥有与您要插入的foreign key 相同的foreign key 行。

【讨论】:

您好,我有同样的问题,但就我而言,我只有一个关系。在这个例子中,它们是外键,我不明白解决方案,你能帮我吗? @jlopez 如果您遇到相同的错误,请检查表中是否有要插入该行的行。必须有一行与要插入的行具有相同的外键。

以上是关于Android Room FOREIGN KEY 约束失败(代码 787)的主要内容,如果未能解决你的问题,请参考以下文章

SQLite with Foreign Key + Models Android Studio CRUD

foreign key

在sql server 2005中,unique、foreign key、primry key约束,check

MySQL FOREIGN_KEY_CHECKS

Foreign_key_check 因工作台导出和 phpmyadmin 失败

删除提示 FOREIGN KEY 约束引用”