Как аннотировать столбец как не NULL с помощью библиотеки сохраняемости Android Room

мой класс данных выглядит так

@Entity(tableName = "items")
data class Item(
        @ColumnInfo(name = "name") var name: String = "",
        @ColumnInfo(name = "room") var room: String = "",
        @ColumnInfo(name = "quantity") var quantity: String = "",
        @ColumnInfo(name = "description") var description: String = "",
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "id") var id: Long = 0
)

Room использует SQLite и SQLite поддерживает не нулевые столбцы в своей базе данных. Я попытался аннотировать столбцы с @NonNull, но это не имеет никакого эффекта.

есть ли способ сделать столбцы в базе данных комнат не nullable?

5 ответов


чтобы определить точную аннотацию для NOT NULL, я прошел через список всех аннотаций, предоставленных по этой ссылке:android.арка.стойкость.комната но не удалось найти соответствующей аннотации:

enter image description here

Я предполагаю, что, поскольку вы используете Kotlin, который по умолчанию рассматривает var как необязательный, все атрибуты, объявленные вами, не являются нулевыми. Чтобы объявить var как необязательный, вероятно, вам нужно использовать a ? оператор, пример ниже:

var name: String // NOT NULL 
var name: String? // OPTIONAL

обновление на основе комментария:

Я думаю, вы путаете с NULL и пустой строкой. NULL означает отсутствие значения, в общем коде вы предоставляете значение по умолчанию для каждого столбца, который является пустой строкой и который не равен NULL, поэтому, даже если вы не могли бы предоставить значение для этого атрибута, по умолчанию ему назначается пустая строка.

Попробуйте удалить оператор присвоения значения и значение RHS для атрибут, а затем вставьте запись без присвоения значения этому атрибуту, вы должны получить соответствующую ошибку.

В основном, преобразовать ниже заявление:

@ColumnInfo(name = "name") var name: String = ""

до

@ColumnInfo(name = "name") var name: String

для Java вы должны аннотировать с @android.поддержка.аннотация.NonNull

Не путайте с @io.реактивекс.комментарии.NonNull


дополнительный ответ для тех, кто использует Котлин:

обратите внимание, что маркировка типа как необязательного автоматически сделает его не нулевым (и необязательный тип этого не сделает).

вы можете проверить его в схеме, сгенерированной room с @Database(exportSchema = true) в вашей базе данных.

например, у меня есть что-то вроде этого:

@Entity(tableName = "messages")
data class Message (
        @PrimaryKey
        val messageId: UUID = UUID.randomUUID(),
        val date: Date = Date(),
        val receivedDate: Date? = null
)

и в сгенерированной схеме я могу прочитать:

"CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (
    `messageId` TEXT NOT NULL, 
    `date` INTEGER NOT NULL, 
    `receivedDate` INTEGER, 
    PRIMARY KEY(`messageId`)
)"

(Примечание: тип даты здесь Int и UUID строка из-за конвертеров, которые я использую в другом месте)


для Java я использовал @NonNull после @ColumnInfo:

@ColumnInfo(name = "column_name")
@NonNull private String str;

убедитесь, что вы импортировали правильную библиотеку в классе:

import android.support.annotation.NonNull;

в качестве обходного пути к фактическим ограничениям таблицы вы можете использовать один класс typeconverter метода, чтобы убедиться, что ваши строковые члены не являются null.

например, для ненулевой строки вы можете использовать:

public class RoomConverterNullString {
    @TypeConverter
    public static String fromNullToString(String value) {
        if (value == null) {
            return "";
        } else {
            return value;
        }
    }
}

вы можете упростить его так, конечно:

public class RoomConverterNullString {
    @TypeConverter
    public static String fromNullToString(String value) {
        return (value == null) ? "" : value;
    }
}

и вы можете использовать его как это:

@TypeConverters(RoomConverterNullString.class)
public String stringMember;

любые назначения и действия обновления / вставки будут хранить пустое строковое значение, когда значение равно null, и любое извлечение будет принудительно преобразовать значение null в пустую строку.

вы можете сделать это для других типов и для любых значений по умолчанию, которые вы хотите иметь.