Reputation: 453
Implementing my domain model in scala using case classes I got
abstract class Entity {
val _id: Option[BSONObjectID]
val version: Option[BSONLong]
}
and several case classes defining the different entities like
case class Person (
_id: Option[BSONObjectID],
name: String,
version: Option[BSONLong]
) extends Entity
What I need is a way to set the _id and version later on from a generic method which operates on an Entity because I have to share this behavior over all Entities and want to avoid writing it down hundreds of times ;-). I would love to be able to
def createID(entity: Entity): Entity = {
entity.copy(_id = ..., version = ...)
}
...but of course this does not compile since an Entity has no copy-method. It is generated for each single case class by the compiler...
What is the best way to achieve this in scala?
To prevent somebody asking: I have to use case classes since this is what the third-party-library is extracting for me from the requests I get and the case class instances are what is serialized back to BSON / MongoDB later on...
Upvotes: 4
Views: 667
Reputation: 453
Indeed one can find a way to implement something like this at
Create common trait for all case classes supporting copy(id=newId) method
but since it is quite complicated for my use case I would prefer just to create two new classes
class MongoId(var id : BSONObjectID = null) {
def generate = {
id = BSONObjectID.generate
}
}
class MongoVersion(var version: Long = 0) {
def update = {
version = System.currentTimeMillis
}
}
and implemented the shared behavior regarding these fields there. Of course you have to change the definition of your base class accordingly:
abstract class Entity {
def _id: MongoId
def version: MongoVersion
}
To make it clear: This works only if the behavior you want to share over several case classes does only affect (in my case changes) one attribute ...
Upvotes: 3
Reputation: 63062
Would implementing a trait work?
trait MongoIdHandler {
def createId(entity : Entity) : Option[BSONObjectID] = { ..}
def setVersion(version : String) : Unit = { ..}
}
case class Person (..) with MongoIdHandler ..
If any of the instances require specialized versions of the id generator they can override the 'default' impl provided by the trait.
Upvotes: 0