【问题标题】:Android Room FOREIGN KEY constraint failed (code 787)Android Room FOREIGN KEY 约束失败(代码 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 列,这会禁止表中的空值。

标签: android sql orm android-room android-orm


【解决方案1】:

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

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

根据SQLite documentation on Foreign Keys

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 您好,我有同样的问题,但就我而言,我只有一个关系。在这个例子中,它们是外键,我不明白解决方案,你能帮我吗?
    • @jlopez 如果您遇到相同的错误,请检查表中是否有要插入该行的行。必须有一行与要插入的行具有相同的外键。
    猜你喜欢
    • 2020-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 2019-10-26
    相关资源
    最近更新 更多