mongodbscalasalat

salat - proper way to append to a list of inner case classes without deserializing the outer object?


I have models like this:

@Salat
class Base
case class Outer(@Key("_id") id:String = "outer", inners:List[Inner] = Nil) extends Base
case class Inner(id:String = "inner") extends Base


object Outer extends SalatDAO[Outer, ObjectId](DBConnections.local("outers"))

If i insert an outer that has an inner, like this:

Outer.insert(new Outer("outer-b", List(new Inner("inner-b"))))

I end up with this in the database:

{
 "_id":"outer-b",
 "_typeHint":"com.github.grinchy.farkle.models.Outer",
 "inners":[
  {
   "_typeHint":"com.github.grinchy.farkle.models.Inner",
   "id":"inner-b"
  }
 ]
}

However, if I just try to append an inner to an outer's list using $push:

Outer.insert(new Outer("outer-a"))

val query = MongoDBObject("_id" -> "outer-a")
val stmt = MongoDBObject("$push" -> MongoDBObject("inners" -> new Inner("inner-a")))

Outer.update(query, stmt)

Then the inner is inserted as an array:

{
 "_id":"outer-a",
 "_typeHint":"com.github.grinchy.farkle.models.Outer",
 "inners":[
  [
   "inner-a"
  ]
 ]
}

What is the proper way to append to a list of inner case classes without deserializing the outer object?


Solution

  • I think you have to register a BSON hook for your type Inner. See the relevant part of documentation