web-dev-qa-db-ja.com

ルームデータベースの一意の制約を複数の列に追加する

部屋にエンティティが1つあります

@Entity(foreignKeys ={
        @ForeignKey(entity = Label.class, parentColumns = "_id", childColumns = "labelId", onDelete = CASCADE),
        @ForeignKey(entity = Task.class, parentColumns = "_id", childColumns = "taskId", onDelete = CASCADE)
})
public class LabelOfTask extends Data{
    @ColumnInfo(name = "labelId")
    private Integer labelId;
    @ColumnInfo(name = "taskId")
    private Integer taskId;
}

このエンティティのSQL構文は次のとおりです

CREATE TABLE `LabelOfTask` (
    `_id` INTEGER PRIMARY KEY AUTOINCREMENT,
     `labelId` INTEGER,
     `taskId` INTEGER,
     FOREIGN KEY(`labelId`) REFERENCES `Label`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE ,
     FOREIGN KEY(`taskId`) REFERENCES `Task`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE
 );

しかし、テーブルの自動生成されたSQLスキーマに以下の制約を追加したい場合、エンティティクラスに追加する必要がある変更または注釈

unique (labelId, taskId)

最終的には、roomライブラリを使用して、labelIdとtaskIdの組み合わせをテーブル(または部屋のエンティティ)で一意にしたいです。

16
Kevan

インデックスを介した以外の列のプレーンなUNIQUE制約はサポートされていません。

@Indexアノテーションのuniqueプロパティをtrueに設定することにより、この一意性プロパティを適用できます。次のコードサンプル(Java)は、firstName列とlastName列に同じ値のセットを含む2つの行がテーブルに含まれないようにします。

@Entity(indices = {@Index(value = {"first_name", "last_name"},
        unique = true)})
class User {
    @PrimaryKey
    public int id;

    @ColumnInfo(name = "first_name")
    public String firstName;

    @ColumnInfo(name = "last_name")
    public String lastName;

    @Ignore
    Bitmap picture;
}

Kotlinに相当する注釈は次のとおりです。

@Entity(indices = arrayOf(Index(value = ["first_name", "last_name"], unique = true)))

コードでは、UNIQUE制約を設定するために次の変更を行うことができます

@Entity(foreignKeys ={
        @ForeignKey(entity = Label.class, parentColumns = "_id", childColumns = "labelId", onDelete = CASCADE),
        @ForeignKey(entity = Task.class, parentColumns = "_id", childColumns = "taskId", onDelete = CASCADE)},
        indices = {@Index(value = {"labelId", "taskId"},
                unique = true)}
)
public class LabelOfTask extends Data{
    @ColumnInfo(name = "labelId")
    private Integer labelId;
    @ColumnInfo(name = "taskId")
    private Integer taskId;
}
23
lib4

単一の列を一意にしたい場合は、書くだけで済みます

@Entity(indices = {@Index(value = "name", unique = true)})
4
Ercan Duman