mongodbcasbahsalat

SalatDAO deserialization of typed class with list


I have the following case classes:

case class Network(val name : String, val mac : String)
case class Field[T](var value : T, var source : String = "")
case class Device(var _id : ObjectId = new ObjectId,
                  var device_type : Field[String] = Field[String](""),
                  var networks : Field[List[Network]] = new Field[List[Network]](List[Network]())) {
  def hasMac(mac : String) : Boolean = {
    networks.value.foreach { n => if(n.mac == mac) return true }
    return false
  }
}

I am able to serialize/deserialze instances of Device. However, after deserializtion, the hasMac method crashed with an exception: "ClassCastException: com.mongodb.BasicDBList cannot be cast to scala.collection.immutable.List"

When the Device class is defined like this

case class Device(var _id : ObjectId = new ObjectId,
                  var device_type : Field[String] = Field[String](""),
                  var networks : List[Network] = List[Network]()) {
  def hasMac(mac : String) : Boolean = {
    networks.foreach { n => if(n.mac == mac) return true }
    return false
  }
}

I don't get the error and everything works as expected.

I saw that salat doesn't support Option[List], but here I have Field[List]. I could not understand from the this page if salat supports this kind of type : https://github.com/novus/salat/wiki/SupportedTypes

Aliza


Solution

  • Salat developer here.

    It looks like Field[List[Network]] is not serializing properly in the first place - BasicDBList is mongo-java-driver's last ditch attempt to serialize your object by treating it as a tuple that gets persisted as a BasicDBList.

    (And wouldn't it save everyone a lot of confusion if you could tell mongo-java-driver to just blow up when it encounters something it doesn't know how to serialize instead of converting it to a list and deferring the issue until the unsuspecting user attempts to deserialize the document?)

    Here's a test showing a parameterized case class that contains a list parameterized to the same type.

    https://github.com/novus/salat/blob/master/salat-core/src/test/scala/com/novus/salat/test/SortedSeqSpec.scala#L44-L49

    However, I can't find any spec proving that a case class parameterized to List[Foo[X]] would work.

    Please file a ticket at https://github.com/novus/salat/issues

    Thanks.