jeudi 12 février 2015

Copy all the fields of a case class when only the mixed in trait is known

First of all, I saw a few similar questions in SO and other forums, but many were for older versions of Scala. I was hoping if there is any other way possible for my situation. Also, I posted the same question in scala and slick google groups, but did not receive any suggestion yet. So was hoping if anyone here could give some suggestions.


I have the below traits/abstract classes in my application.



trait Persistable

abstract class BaseEntity extends Persistable{
val id:Long
}

trait Auditable {
val createdDate: java.sql.Timestamp
val modifiedDate : java.sql.Timestamp
}


All the table which are auditable will have created and modified dates. One of my case classes looks like this.



case class UserAccount(overide val id:Long, name:String, override val createdDate:java.sql.Timestamp,
override val modifiedDate: java.sql.Timestamp)
extends BaseEntity with Auditable


My application is a spray and slick based REST application. I am parsing the json sent from the client side into the required case class. Now, I want to set the createdDate and modifiedDate in the application, rather than just saving what the client sends. There are two reasons for that, as I do not want to have timezone difference issues and also don't want anyone to mess up the createdDate/modifiedDate intentionally as well.


I am following the repository pattern to handle all the database operation in a central location.



trait Repository[TTable <: BaseTable[TEntity], TEntity <: Persistable[Long]] {

def insert(row: TTable#TableElementType): TEntity = {
db.withSession { implicit session =>
if (row.isInstanceOf[Auditable]) {
// set the modifiedDate and createdDate here
(query returning query.map(obj => obj) += row).asInstanceOf[TEntity]
} else {
(query returning query.map(obj => obj) += row).asInstanceOf[TEntity]
}
}
}

}


How can I copy the whole row and modify only createdDate and modifiedDate. I guess this can be achieved by using reflection, but I read suggestions to avoid the reflection. Is there any other way to achieve this functionality. It is not just this case, I have a few other situations where if the case class is mixed in with another trait, modify some other fields.






Aucun commentaire:

Enregistrer un commentaire