我有以下实体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;
}
在删除附加到Label
的{{1}}时,我得到的是Session
的{{1}}。
我在这里做什么错了?
答案 0 :(得分:2)
我认为问题在于使用public boolean archived = false;
中的布尔类型。
由于 boolean 是Java主要类型,因此它具有隐式 @NonNull (表是使用NOT NULL约束创建的)
在“房间”中,您无法(我相信)设置在SQLite表中生成的默认值,因此当使用onDelete SET_DEFAULT
时,默认值将为 NULL ,因为尚未设置实际的默认值
Note Room现在使用defaultValue()批注中的@ColumnInfo支持默认值。
使用= false
不会影响实际的SQLite表,即,如果使用 Boolean ,则列定义将是labelId INTEGER
而不是labelId INTEGER DEFAULT 0
。 / p>
假设NULL是可接受的,则可以使用 Boolean (对象)而不是boolean(主要类型)。对象可以为空。
即在会话中使用
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)
如果您希望Session表中的存档列为0(假),则必须修改该表。这将需要
label INTEGER DEFAULT 0
(即添加DEFAULT 0)之外,其他相同INSERT INTO replacement_Session SELECT * FROM Session;
或者(我认为),您可以使用AFTER UPDATE TRIGGER将NULL更改为0(假)。
这两个选项都必须在Room之外或在RoomDatabase构建之前完成。
答案 1 :(得分:0)
参考this。如果您使用 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?
)