В моей кодовой базе Kotlin Android у меня есть следующие 2 объекта.
@Entity(
tableName = ModuleConfiguration.tableName,
primaryKeys = [ModuleConfiguration.COL_ID],
foreignKeys = arrayOf(
ForeignKey(
entity = Module::class,
parentColumns = [Module.COL_ID],
childColumns = [ModuleConfiguration.COL_MODULE_ID],
onDelete = ForeignKey.CASCADE
),
ForeignKey(
entity = Group::class,
parentColumns = [Group.COL_ID],
childColumns = [ModuleConfiguration.COL_GROUP_ID]
)
)
)
class ModuleConfiguration(
@ColumnInfo(name = COL_ID)
var id: String = UUID.randomUUID().toString(),
@ColumnInfo(name = COL_TABLE)
var table: String,
@ColumnInfo(name = COL_FIELD_NAME)
var fieldName: String,
@ColumnInfo(name = COL_FIELD_LABEL)
var fieldLabel: String,
@ColumnInfo(name = COL_FIELD_TYPE)
var fieldType: ModuleConfigurationItemType,
@ColumnInfo(name = COL_GROUP_ID)
var groupId: String?,
@ColumnInfo(name = COL_MODULE_ID)
var moduleId: String,
@ColumnInfo(name = COL_POSITION)
var position: Int,
@ColumnInfo(name = COL_VISIBLE)
var visible: Int = 1, //Usually visible
@ColumnInfo(name = COL_READ_ONLY)
var readOnly: Int = 0, //Usually false
@ColumnInfo(name = COL_REQUIRED)
var required: Int = 0, //Usually false
@ColumnInfo(name = COL_CREATED_AT)
var createdAt: Long = CustomDateTimeUtil.getTodayInUTC(),
@ColumnInfo(name = COL_UPDATED_AT)
var updatedAt: Long = CustomDateTimeUtil.getTodayInUTC()
) : Cloneable, Serializable, Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString() ?: "",
parcel.readString() ?: "",
parcel.readString() ?: "",
parcel.readString() ?: "",
fieldType = ModuleConfigurationItemType.valueOf(parcel.readString() ?: FieldType.UNKNOWN.name),
groupId = parcel.readString(),
moduleId = parcel.readString() ?: "",
position = parcel.readInt(),
visible = parcel.readInt(),
readOnly = parcel.readInt(),
required = parcel.readInt(),
createdAt = parcel.readLong(),
updatedAt = parcel.readLong()
) {
}
fun getViewType() : ModuleConfigurationItemType {
return this.fieldType
}
override fun equals(other: Any?): Boolean {
return super.equals(other)
}
override fun hashCode(): Int {
return super.hashCode()
}
override fun clone(): Any {
return super.clone()
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(id)
parcel.writeString(table)
parcel.writeString(fieldName)
parcel.writeString(fieldLabel)
parcel.writeString(fieldType.name)
parcel.writeString(groupId)
parcel.writeString(moduleId)
parcel.writeInt(position)
parcel.writeInt(visible)
parcel.writeInt(readOnly)
parcel.writeInt(required)
parcel.writeLong(createdAt)
parcel.writeLong(updatedAt)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<ModuleConfiguration> {
const val tableName = "module_configuration"
const val COL_ID = "id"
const val COL_MODULE_ID = "module_id"
const val COL_TABLE = "table"
const val COL_FIELD_NAME = "field_name"
const val COL_FIELD_LABEL = "field_label"
const val COL_FIELD_TYPE = "field_type"
const val COL_GROUP_ID = "group_id"
const val COL_VISIBLE = "visible"
const val COL_READ_ONLY = "read_only"
const val COL_REQUIRED = "required"
const val COL_POSITION = "position"
const val COL_CREATED_AT = "created_at"
const val COL_UPDATED_AT = "updated_at"
const val COL_CLIENT_ID = "client_id"
override fun createFromParcel(parcel: Parcel): ModuleConfiguration {
return ModuleConfiguration(parcel)
}
override fun newArray(size: Int): Array<ModuleConfiguration?> {
return arrayOfNulls(size)
}
}
}
и Группа
@Entity(
tableName = Group.tableName,
primaryKeys = [Group.COL_ID]
)
class Group(
@ColumnInfo(name = COL_ID)
var id: String = UUID.randomUUID().toString(),
@ColumnInfo(name = COL_NAME)
var name: String,
@ColumnInfo(name = COL_CREATED_AT)
var createdAt: Long = CustomDateTimeUtil.getTodayInUTC(),
@ColumnInfo(name = COL_UPDATED_AT)
var updatedAt: Long = CustomDateTimeUtil.getTodayInUTC()
) : Cloneable, Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString() ?: "",
parcel.readString() ?: "",
parcel.readLong(),
parcel.readLong()
) {
}
override fun equals(other: Any?): Boolean {
return super.equals(other)
}
override fun hashCode(): Int {
return super.hashCode()
}
override fun clone(): Any {
return super.clone()
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(id)
parcel.writeString(name)
parcel.writeLong(createdAt)
parcel.writeLong(updatedAt)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Group> {
const val tableName = "group"
const val COL_ID = "id"
const val COL_NAME = "name"
const val COL_CREATED_AT = "created_at"
const val COL_UPDATED_AT = "updated_at"
const val COL_CLIENT_ID = "client_id"
override fun createFromParcel(parcel: Parcel): Group {
return Group(parcel)
}
override fun newArray(size: Int): Array<Group?> {
return arrayOfNulls(size)
}
}
}
Моя проблема в том, что я пытаюсь установить обнуляемый внешний ключ, как вы можете видеть в объекте с именем ModuleConfiguration, есть столбец с именем group_id, который обнуляемый.
@ColumnInfo(name = COL_GROUP_ID)
var groupId: String?,
Поскольку этот столбец принадлежит другому объекту с именем Группа, я пытаюсь сделать его внешним ключом, но когда я это делаю, я получаю следующую ошибку
SQLiteConstraintException: ограничение FOREIGN KEY не удалось (код 787)
При поиске в Интернете я нашел следующие ответы на stackoverflow:
Android с комнатой - Как установить внешний ключ с нулевым значением или Нулевой внешний ключ в комнате
но это мне не помогло, поскольку в этом ответе предлагается изменить примитивные типы, такие как int или long, на непримитивные типы, такие как Integer или Long, чтобы они были нулевыми. Я уже использую String как тип.
Любая помощь будет высоко оценен.
Заранее спасибо.
moduleId
, который не может быть нулевым? - person sergiy tikhonov   schedule 15.10.2020