我有以下实体,Session
和Label
:
@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;
}
删除附加到Session
的Label
时,我得到了Session.archived
的NOT NULL constraint failed
。
我在这里做错了什么?
我相信问题在于使用一种布尔值,如public boolean archived = false;
.
由于布尔值是 Java 主要类型,因此它具有隐式@NonNull(该表是使用 NOT NULL 约束创建的(
使用 Room,您不能(我相信(设置在 SQLite 表中生成的默认值,因此在使用onDelete SET_DEFAULT
时,默认值将为NULL,因为没有设置实际的默认值。
注意 Room 现在支持在@ColumnInfo批注中使用 defaultValue(( 的默认值。
使用
= false
不会影响实际的 SQLite 表,即列定义,如果使用布尔值,将labelId INTEGER
不labelId 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(,则必须修改该表。这将需要
- 创建一个相同的替换表,只是标签列定义将被
label INTEGER DEFAULT 0
(即添加 DEFAULT 0( - 将数据从会话表复制到替换表中,例如
INSERT INTO replacement_Session SELECT * FROM Session;
- 重命名会话表 。
- 将替换表重命名为会话。
- 如果满意,请删除重命名的会话表。
或者(我认为(您可以使用更新后触发器将 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?
)