5

I am trying to implement schema default values which came with Room 2.2 to my entity but it does not seem to work.

I have an entity called Place:

@Entity
public class Place implements Parcelable {

    @PrimaryKey(autoGenerate = true)
    private Long placeId;

    private String name;

    private double latitude;

    private double longitude;

    private int radius;

    @ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")
    private String createdAt;

    @Ignore
    public Place() {}

    public Place(String name, double latitude, double longitude, int radius) {
        this.name = name;
        this.latitude = latitude;
        this.longitude = longitude;
        this.radius = radius;
    }

    // getters and setters...

    public String getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(String createdAt) {
        this.createdAt = createdAt;
    }

}


When a place is inserted into the database, createdAt field is always getting inserted as NULL.

enter image description here


Changing createdAt variable into long replaces fields with 0.

What am I doing wrong here?

Mertcan Seğmen
  • 903
  • 2
  • 11
  • 26
  • What makes you think that it should work? There is no mention of `@ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")` in the official documentation of Room. – Sergey Emeliyanov Dec 15 '19 at 01:10
  • 1
    see [how to automatically set timestamp in room sqlite database](https://stackoverflow.com/questions/59323938/how-to-automatically-set-timestamp-in-room-sqlite-database/59326573) – MikeT Dec 15 '19 at 01:10
  • @SerjArdovic see [defaultValue](https://developer.android.com/reference/androidx/room/ColumnInfo.html#defaultValue()) – MikeT Dec 15 '19 at 01:12
  • 1
    I watched [this](https://youtu.be/_aJsh6P00c0?t=713), did I get it wrong? – Mertcan Seğmen Dec 15 '19 at 01:17
  • @MikeT, it's virtually a duplicate question, basically the answer suggests that `@Insert()` doesn't work, yet more specific `@Query("INSERT INTO test_table001 (name) VALUES(:name) ")` does work.. interesting – Sergey Emeliyanov Dec 15 '19 at 01:17
  • @MertcanSeğmen, seeing that it's quite new feature, might be experimental.. again consider updating your dependencies (Room, androidx..) to the most recent versions, might help. – Sergey Emeliyanov Dec 15 '19 at 01:21

1 Answers1

5

You can use @Query with specfific column names (and values), excluding those to be defaulted to.

As per :-

Note that the default value you specify here will NOT be used if you simply insert the Entity with @Insert. In that case, any value assigned in Java/Kotlin will be used. Use @Query with an INSERT statement and skip this column there in order to use this default value. defaultValue

So in this case you can use :-

@Query("INSERT INTO Place (name,latitude,longitude,radius) VALUES(:name,:latitude,:logitude,:radius)")

The reason is that with the exception of an alias of the rowid. If null is passed where a column name has been specified either explicitly or implicitly then the default value is not used so the value store is null.

consider :-

DROP TABLE IF EXISTS place;
CREATE TABLE IF NOT EXISTS `Place` (`placeId` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT, `latitude` REAL NOT NULL, `longitude` REAL NOT NULL, `radius` INTEGER NOT NULL, `createdAt` TEXT DEFAULT CURRENT_TIMESTAMP);

INSERT INTO place VALUES(null,'opt1',0,0,0,null); //<<<< As per @Insert
INSERT INTO place (name,latitude,longitude,radius) VALUES('opt2',1,1,1); //<<<< As per @Query
SELECT * FROM place;

The results in :-

enter image description here

Room actually builds the following 2 queries (as per the generated code)

"INSERT OR ABORT INTO `Place` (`placeId`,`name`,`latitude`,`longitude`,`radius`,`createdAt`) VALUES (?,?,?,?,?,?)"

and

"INSERT INTO place (name,latitude,longitude,radius) VALUES(?, ?, ?, ?)"
MikeT
  • 51,415
  • 16
  • 49
  • 68
  • What could be then If the value of one field needs to be inserted as the default value unless it is set? Suppose, -1 as the default value is inserted if not set earlier. Then in some cases, the value could be specified where it will insert the default value. – Patriotic May 31 '20 at 01:01
  • In this case, I have solved this by simply putting a default value in the member variable and then update it via setter if required. – Patriotic May 31 '20 at 01:13