文件室数据库:删除时约束不为 NULL 失败



我有以下实体,SessionLabel

@Entity(
foreignKeys =
@ForeignKey(
entity = Label.class,
parentColumns = {"id", "archived"},
childColumns = {"labelId", "archived"},
onUpdate = CASCADE,
onDelete = SET_DEFAULT))
public class Session {
@PrimaryKey(autoGenerate = true)
public long id;
@Nullable
public String label = null;
public boolean archived = false;
}
@Entity(primaryKeys = {"id", "archived"})
public class Label {
@NonNull
public String id;
public boolean archived = false;
}

删除附加到SessionLabel时,我得到了Session.archivedNOT NULL constraint failed

我在这里做错了什么?

我相信问题在于使用一种布尔值,如public boolean archived = false;.

由于布尔值是 Java 主要类型,因此它具有隐式@NonNull(该表是使用 NOT NULL 约束创建的(

使用 Room,您不能(我相信(设置在 SQLite 表中生成的默认值,因此在使用onDelete SET_DEFAULT时,默认值将为NULL,因为没有设置实际的默认值。

  • 注意 Room 现在支持在@ColumnInfo批注中使用 defaultValue(( 的默认值。

  • 使用= false不会影响实际的 SQLite 表,即列定义,如果使用布尔值,将labelId INTEGERlabelId INTEGER DEFAULT 0

假设 NULL 是可接受的,那么您可以使用布尔值(对象(而不是布尔值(主要类型(。对象可以为空。

即在会话中使用

public Boolean archived = false;

目视切除:-

以下是由 Room 为会话实体生成的代码,但使用 :- 添加了附加列

.........
public boolean archived = false;
public Boolean other_archived = false; //<<<<<<<<<< ADDED
........

房间生成的代码:-

CREATE TABLE IF NOT EXISTS `Session` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
`label` TEXT, 
`archived` INTEGER NOT NULL, /*<<<<<<<<<< boolean so NOT NULL */ 
`other_archived` INTEGER, /*<<<<<<<<<< Boolean so no NOT NULL */
FOREIGN KEY(`label`, `archived`) REFERENCES `Label`(`id`, `archived`) ON UPDATE CASCADE ON DELETE SET DEFAULT)

额外

如果希望会话表中的存档列为 0 (false(,则必须修改该表。这将需要

  1. 创建一个相同的替换表,只是标签列定义将被label INTEGER DEFAULT 0(即添加 DEFAULT 0(
  2. 将数据从会话表复制到替换表中,例如INSERT INTO replacement_Session SELECT * FROM Session;
  3. 重命名会话表 。
  4. 将替换表重命名为会话。
  5. 如果满意,请删除重命名的会话表。

或者(我认为(您可以使用更新后触发器将 NULL 更改为 0(假(。

任何一个选项都必须在房间外部或在构建房间数据库之前完成。

指的是这个。如果您使用 Kotlin 进行编码,为了使模型字段可为空,请不要使用 @Nullable而是通过使用"?"使字段可为空。 以下字段不可为空。

@Entity(tableName = "books")
data class Book(
@PrimaryKey
val id: Int,
val title: String,
val description: String,
val info: String,
val type: Int,
val url: String
)

但以下字段可为空:

@Entity(tableName = "books")
data class Book(
@PrimaryKey
val id: Int,
val title: String?,
val description: String?,
val info: String?,
val type: Int,
val url: String?
)

最新更新