Best way to instantiate an Android Room Entity object for insertion without specifying the autogenerated PK? (Kotlin)

In Android, when using the Room database and using an auto-generated primary key, your pk will be a field of the object and therefore will need to be set when you create a plain-old Kotlin object. So what is a correct and clean way to instantiate an object that you use for insertion?

Say you have a table like so:

@Entity(tableName = "data")
class Data(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Long,
    @ColumnInfo(name = "some_data") val someData: Int
)

If you want to actually insert a Data object, you will need to specify the id at initialization.

I see two possibilities, and am unsure if either are correct:

Upvotes: 3

Views: 1830

Answers (2)

Denis Korobitsin
Denis Korobitsin

Reputation: 106

This worked for me:

@Entity(tableName = "data")
class Data(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Long = 0,
    @ColumnInfo(name = "some_data") val someData: Int
)


fun generateData(name: String): Data {
    return Data(name=name)
}

Upvotes: 3

MikeT
MikeT

Reputation: 56948

If within a Dao have :-

@Insert
fun insertDataRow(data: Data): Long
  • Thus the id of the inserted row will be returned

and then use

insertedId = myMado.insertDataRow(0,10)

The insertedId will be the generated id.

If you use Int? then you could use

insertedId = myMado.insertDataRow(null,10)

If with Int? if you used (with no existing data)

insertedId = myMado.insertDataRow(0,10)
insertedId = myMado.insertDataRow(0,11)

The you would get a UNIQUE constraint exception for the second insert as the id is set to 0.

That is there is a subtle change if you use Int? as opposed to Int. Int effectively treats 0 as null whilst the Int? treats 0 as the value 0

  • P.S. ideally you should use Long or Long? for the id as it can be a 64bit signed integer.

Upvotes: 1

Related Questions