web-dev-qa-db-fra.com

Comment annoter une colonne comme NON NULL à l'aide de Android Bibliothèque de persistance de pièce

Ma classe de données ressemble à ceci

@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 utilise SQLite et SQLite prend en charge les colonnes NOT NULL dans sa base de données. J'ai essayé d'annoter des colonnes avec @NonNull mais cela n'a aucun effet.

Existe-t-il un moyen de rendre les colonnes de la base de données de salle non nullables?

16
Tuby

Afin d'identifier l'annotation exacte de NOT NULL, j'ai parcouru la liste de toutes les annotations fournies sur ce lien: Android.Arch.persistence.room mais je n'ai trouvé aucune annotation pertinente:

enter image description here

Mon hypothèse est que puisque vous utilisez Kotlin, qui par défaut traite un var comme non optionnel, tous les attributs déclarés par vous ne sont PAS NULS. Pour déclarer un var comme facultatif, vous devez probablement utiliser un? opérateur, un exemple ci-dessous:

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

Mis à jour en fonction des commentaires:

Je suppose que vous êtes confondu avec NULL et chaîne vide. NULL signifie aucune valeur, dans le code partagé, vous fournissez une valeur par défaut à chaque colonne qui est une chaîne vide et qui n'est pas égale à NULL, donc même si vous n'avez peut-être pas fourni de valeur pour cet attribut, il s'agit par défaut d'attribuer un chaîne vide.

Essayez de supprimer l'opérateur d'attribution de valeur et la valeur RHS pour un attribut, puis insérez l'enregistrement sans affecter de valeur à cet attribut, vous devriez obtenir l'erreur appropriée.

Fondamentalement, convertissez la déclaration ci-dessous:

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

À

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

Pour Java vous devez annoter avec @ Android.support.annotation.NonNull

NE PAS CONFONDRE AVEC @ io.reactivex.annotations.NonNull

36
Nokuap

Pour Java j'ai utilisé @NonNull après le @ColumnInfo:

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

Assurez-vous d'avoir importé la bonne bibliothèque dans la classe:

import Android.support.annotation.NonNull;
8
avisper

Réponse complémentaire pour ceux qui utilisent Kotlin:

veuillez noter que le marquage d'un type comme non facultatif ne le rendra pas automatiquement nul (et un type facultatif ne le fera pas).

Vous pouvez le vérifier dans le schéma généré par room avec @Database(exportSchema = true) sur votre base de données.

Par exemple, j'ai quelque chose comme ça:

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

Et dans le schéma généré, je peux lire:

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

(Remarque: le type Date est ici un Int et l'UUID une chaîne en raison de convertisseurs que j'utilise ailleurs)

7
Vincent Hiribarren

Pour contourner les contraintes de table réelles, vous pouvez utiliser une classe TypeConverter de méthode unique pour vous assurer que vos membres String ne sont pas nuls.

Par exemple, pour une chaîne non nulle, vous pouvez utiliser:

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

Vous pouvez bien sûr le simplifier comme ceci:

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

Et vous pouvez l'utiliser comme ceci:

@TypeConverters(RoomConverterNullString.class)
public String stringMember;

Toutes les affectations et actions de mise à jour/insertion stockent une valeur de chaîne vide lorsque la valeur est nulle et toute récupération force une valeur nulle à être convertie en chaîne vide.

Vous pouvez le faire pour d'autres types et pour toutes les valeurs par défaut que vous souhaitez avoir.

2
Evan I