Define custom serialization with Casbah / Salat - or delegate serialization to member? Define custom serialization with Casbah / Salat - or delegate serialization to member? mongodb mongodb

Define custom serialization with Casbah / Salat - or delegate serialization to member?


Salat maintainer here.

I don't understand the value of Description as a wrapper here. It wraps a map of attributes, overrides the default equals and hashcode impl of a case class - which seems unnecessary since the impl is delegated to the map anyhow and that is exactly what the case class does anyway - and introduces an additional layer of indirection to the serialized object.

Have you considered just:

case class Person(val name: String, val description: Map[String, String])

This will do exactly what you want out of box.

In another situation I would recommend a simple type alias but unfortunately Salat can't support type aliases right now due to some issues with how they are depicted in pickled Scala signatures.

(You probably omitted this from your example from brevity, but it is best practice for your Mongo model to have an _id field - if you don't, the Mongo Java driver will supply one for you)

There is a working example of a custom BSON hook in the salat-core test package (it handles java.net.URL). It could be that your hook is not working simply because you are not registering it in the right place? But still, I would recommend getting rid of Description unless it is adding some value that is not evident from your example above.


Based on @prasinous' answer I decided this wasn't going to be that easy so I've changed my design a bit to the following, which pretty much gets me what I want. Rather than persisting the Description as a field I persist a vanilla map then mix in a Described trait to the model classes I want to have a description, which automatically converts the map to Description when the object is created. Would appreciate it if anyone can point out any obvious problems to this approach or any suggestions for improvement.

class Description(val attributes: Map[String, String]){  //rest of class omitted}trait Described {  val attributes: Map[String, String]  val description = new Description(attributes)}case class Person(name: String, attributes: Map[String, String]) extends Described