score:2

Accepted answer

first, what the error tells you is that you shouldn't have a case class for a class which is extended. the thing it says about extractors is basically that, should the need arise to pattern match on a parent class (which is what the case of case class comes from, easy pattern matching), you can always write custom extractors for it.

however, this does not apply in your case, since you cannot change the fact that your lib exposes case classes.

the other solution, is to consider that there is no inheritance between your two classes. indeed, one is the representation of a user, while the other is the representation of a storage unit containing a user. so it looks like your proposed solution has some meaning after all.

still, it might seem cumbersome to have to add a field, both in the serialized object (in mongo) and in the jvm class, where you will need to always do mongouser.user to get a lib.myuser from a myuser...

one elegant (imho) solution is to keep this field user: lib.myuser, but to have your serialization flatten this field to the top level of the bson object, so that a serialized myuser will look like

{
  _id: objectid(_),
  id: 123456789abc-1234-1234-1234,
  ...
}

as if you had inherited the fields of lib.myuser.

deserialization

now, whenever you want to get a lib.myuser from mongo, for read purposes only, you can deserialize it directly in this format, ignoring the added fields. if you need to do some updates on it however, you will have to deserialize it as a myuser, to be able to update this particular bson document.

scala usage

when you have deserialized the object as a myuser (say, for an update), you might still want an easy access to all fields exposed in lib.myuser, without having to access the field user every time. this can be done with an implicit conversion.

generalization

by the way, you can do this for any object that you want serialized, in a generic way...

to sum it all up

case class mongorepr[t](_id: option[bsonobjectid]
                         value: t,
                         created: option[datetime],                             
                         updated: option[datetime])

object mongorepr {
  //implement flattened (de)serialization, this depends on your
  // mongo driver and what you're using for serialization (json/bson)
  def handler[t](implicit handlert: bsonhandler[t]): bsonhandler[mongorepr[t]] = ???

 implicit def tovalue[t](repr: mongorepr[t]): t = repr.value
}

Related Query

More Query from same tag