My app is currently using retrofit and Room but I am struggling to find a way to autogenerate the id of the Db object. When mapping retrofit object to the RoomDb entity, it keeps asking for an id to filed up even if I added the autogenerate key
Below is the retrofit object:
data class RetrofitProduct(
@SerializedName("id")
val id: String,
@SerializedName("types")
val types: List<String>,
@SerializedName("date")
val date: String,
)
and the associated Room Entity:
@Entity
data class ProductEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Int,
@ColumnInfo(name = "productId")
val productId: String,
@ColumnInfo(name = "types")
val types: List<String>,
)
the Mapper is as below:
fun RetrofitProduct.toEntity(): ProductEntity {
return ProductEntity(
productId = this.id,
types = this.types,
)
}
But at build time, the compiler complains that I need to add the id
:
No value passed for parameter 'id'
I want this id to be generated by Room as a way to get the number of items for my paging.
Basically if I pull the lastItem, I know that with the id is for example: 25. So I need to ask for 26 and more.
This is actually a pretty common gotcha when working with Room and auto-generated IDs. The problem is that even though you've marked the ID as autoGenerate = true, Kotlin still requires all parameters to be provided in the constructor since ProductEntity is a data class. Here are a couple of ways to solve this:
The quickest fix - provide a default value of 0:
kotlinCopy@Entity
data class ProductEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Int = 0, // Add this default value
@ColumnInfo(name = "productId")
val productId: String,
@ColumnInfo(name = "types")
val types: List<String>,
)
Or if you prefer being more explicit in your mapper:
kotlinCopyfun RetrofitProduct.toEntity(): ProductEntity {
return ProductEntity(
id = 0, // Room will ignore this and auto-generate
productId = this.id,
types = this.types,
)
}
Room will ignore the 0 value and auto-generate a new ID when you insert the entity. This works because Room checks for 0 or null (depending on if you're using nullable types) as signals to auto-generate the ID. When you use this approach for paging, you can still query the last item's ID just fine since Room will have replaced that 0 with the actual auto-generated value.