Why does the author define the table fields in two position in Room with Android Jetpack?

The declaration of a property inside the data class constructor is used to :

  1. Generate component function for destructing
  2. Use these fields inside the toString(), equals(), hashCode(), and copy()

So if you want to avoid copying fields with the copy method then the easy way is to declare the fields inside the body of the class.

Example:

fun main() {
    val user = User("Pavneet", "29k+")
    user.id = kotlin.random.Random.nextInt(10, 20)
    val userCopy = user.copy()
    println(userCopy) // id won't be printed 'cuz it's not a part of toString method
    userCopy.id = 99
    print(userCopy.equals(user)) // true, 'cuz id is not being used by the equals method
    //var(name, repo, id) = userCopy // error, User must have a 'component3()' function
    var(name, repo) = userCopy

}

data class User(val name: String = "", val repo:String="0"){
    var id:Int = 0
}

Advantages:

  1. Create a copies of the object excluding specific fields
  2. Exclude specific fields to compare two objects with equals
  3. Exclude specific fields in destructuring declarations

Note: copy and component methods cannot be provided explicitly(inside data class). In example B, gardenPlantingId is replaced with id so can be removed.


The answer is very simple:

Because in this sample code, the author wants to show that we can use both @PrimaryKey and @ColumnInfo annotation to ANY member inside an entity class, regardless its position (it can be in the inside the constructor or at the outside).

To experiment with this, you can just do exactly what you did on Code B. It is also valid, but in that case, gardenPlantingId will not have a custom column name because we don't use @ColumnInfo annotation. Also, it is not necessary to declare @PrimaryKey outside the constructor (like the given example). You can just declare your the primary key annotation inside the constructor.