Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No "NOT NULL" and "UNIQUE" constraint on Room Persistence Library

While playing with the Room Persistence Library I came to know that there is no methodology to set a data class field with NOT NULL and also UNIQUE constraints. whether SQLite supports those constraints. Isn't it a problem to migrate old database where those constraints are used? Can anyone give a suggestion for this issue?

like image 302
raggedycoder Avatar asked Sep 04 '17 05:09

raggedycoder


3 Answers

I came to know that there is no methodology to set a data class field with NOT NULL and also UNIQUE constraints

A @NonNull annotation on an @Entity field will cause that field's column to have NOT NULL applied to it.

unique=true on an @Index will enforce a uniqueness constraint (e.g., @Entity(indices={@Index(value="something", unique=true)}). However, you are correct that a plain UNIQUE constraint on a column, other than via an index, is not supported.

Isn't it a problem to migrate old database where those constraints are used?

Room is not designed to support existing database structures, particularly in the now-current alpha state. Over time, I would expect Room to support a higher percentage of SQLite features, though I will be stunned if it ever reaches 100%.

like image 73
CommonsWare Avatar answered Nov 10 '22 10:11

CommonsWare


Complementary answer about NOT NULL for those using Kotlin:

please note that marking a type as non optional will automatically make it not null (and an optional type will not do that).

You can check it in the schema generated by room with @Database(exportSchema = true) on your database.

For example I have something like that:

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

And in the generated schema I can read:

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

(Note: the Date type is here an Int and the UUID a string due to converters I use elsewhere)

like image 6
Vincent Hiribarren Avatar answered Nov 10 '22 11:11

Vincent Hiribarren


If you have multiple item that is to be marked unique & based on that you want to insert in db then you can use composite primary key.

For Not null, Room has provided "@NonNull" annotation that is added over the field that cannot be null.

In the below mentioned eg. roll number is unique in each class but 2 different class can have same roll number. So we can use class & rollNumber as composite primary key & insert in db uniquely. Example:

    @Entity(primaryKeys = {"rollNumber", "class"})   
    class Student {
       @NonNull
        private int rollNumber;
        private String firstName;
        private String lastName;
        private int class;
        } 
like image 1
Ashish John Avatar answered Nov 10 '22 10:11

Ashish John