1

I have a list of fields I would like every entity to have, so I've created a Base Entity.

open class Syncable(
    @ColumnInfo(name = "id")
    var oid: String? = null,
    @ColumnInfo(name = "created")
    var created: Long = System.currentTimeMillis(),
    @ColumnInfo(name = "updated")
    var updated: Long = System.currentTimeMillis())

Then I have a number of entities inheriting from this one, like:

@Entity(tableName = ProfileContract.TABLE_NAME, indices = [Index(value = ["id"], unique = true)])
data class Profile(ColumnInfo(name = "first_name")
     var firstName: String,
     @ColumnInfo(name = "last_name")
     var lastName: String,          
     @ColumnInfo(name = "email")
     var email: String? = null,
     @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "row_id")
     var id: Long? = null) : Syncable()

Now when I want to construct one of these entities. How do I do it?

Currently I do:

val newProfile = Profile(
                    "Bob",
                    "Shoruncle",
                    "bobshoruncle@test.com)
newProfile.id = "bob1"
newProfile.created = 1233L
newProfile.updated = 1233L

Is there a way to do it as:

val newProfile = Profile("Bob", "Shoruncle", "bobshoruncle@test.com","bob1",1233L,1233L)
Cory Roy
  • 5,379
  • 2
  • 28
  • 47

2 Answers2

2

@a_local_nobody was on the right track, but the answer is more complex.

I need to create a custom constructor on the child class that will set the fields of the parent class

 @Entity(tableName = ProfileContract.TABLE_NAME, indices = [Index(value = ["id"], unique = true)])
 data class Profile(ColumnInfo(name = "first_name")
 var firstName: String,
 @ColumnInfo(name = "last_name")
 var lastName: String,          
 @ColumnInfo(name = "email")
 var email: String? = null,
 @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "row_id")
 var id: Long? = null) : Syncable() {
 @Ignore constructor(
   firstName: String,
   lastName: String,
   email: String,
   id: String,
   created: Long,
   updated:Long) : this(firstName, lastName, email) {
     this.id = id
     this.created = created
     this.updated = updated
   }
 }

Now to external creators it looks like one big constructor

Cory Roy
  • 5,379
  • 2
  • 28
  • 47
  • Out of curiosity, how does updating compare to using `@Embedded`? –  Jul 17 '19 at 23:14
  • With inheritance you update the field like it was in the child object, with simple dot notation, you do not need to construct an inner object first. `@Embedded` collapses the object into the db table, but it still exists in the data object as it's own inner class. – Cory Roy Jul 18 '19 at 18:05
  • 1
    damn, that's what i was trying to achieve :P i'll upvote your answer though, good job for finding it, glad i could kinda help :) – a_local_nobody Jul 21 '19 at 07:49
0

Could you not maybe do something like this:

open class Syncable(
    @ColumnInfo(name = "id")
    var oid: String? = null,
    @ColumnInfo(name = "created")
    var created_on: Long = System.currentTimeMillis(),
    @ColumnInfo(name = "updated")
    var updated_on: Long = System.currentTimeMillis())

@Entity(tableName = ProfileContract.TABLE_NAME, indices = [Index(value = ["id"], unique = true)])
data class Profile(ColumnInfo(name = "first_name")
     var firstName: String,
     @ColumnInfo(name = "last_name")
     var lastName: String,          
     @ColumnInfo(name = "email")
     var email: String? = null,
     @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "row_id")
     var id: Long? = null) : Syncable(){
    constructor(profile: Account) : this(profile.firstName, profile.lastName, profile.email, profile.id,profile.oid, profile.created_on, profile.updated_on)
}

Basically, try looking at calling super method constructors for kotlin

I tried to base my answer off of this post here, have a look, hope it helps : Call super class constructor in Kotlin, Super is not an expression

a_local_nobody
  • 7,947
  • 5
  • 29
  • 51