Skip to content
rktoomey edited this page Sep 4, 2012 · 6 revisions

Type hinting

Salat uses a type hint field named _typeHint to record class information when serializing to DBObject.

  case class Alpha(x: String)

  scala> import com.novus.salat.global._
  import com.novus.salat.global._

  scala> val a = Alpha(x = "Hello world")
  a: com.novus.salat.test.model.Alpha = Alpha(Hello world)

  scala> val dbo = grater[Alpha].asDBObject(a)
  dbo: com.mongodb.casbah.Imports.DBObject = { "_typeHint" :  "com.novus.salat.test.model.Alpha" , "x" : "Hello world"}

  scala> val a_* = grater[Alpha].asObject(dbo)
  a_*: com.novus.salat.test.model.Alpha = Alpha(Hello world)

  scala> a == a_*
  res0: Boolean = true

The default is to always use type hints, but you can control the type hint name and behavior.

Normally, the Salat global context will provide what you want:

import com.novus.salat.global._

But you can control this by using a custom context.

Type hinting strategies

Salat supports the following type hinting strategies:

  • always (verbose but good for testing)
  • "When necessary" (default)
  • never (not recommended!)

Type hints are necessary when you need to support using @Salat with a field or collection typed to a trait or an abstract superclass. Both always and when necessary will suport this.

Type hints are also necessary when you want to look up a grater using a DBObject. The only strategy that provides this flexibility is always.

If you never need to use traits or abstract superclasses and always already have a grater in hand to deserialize your objects, you can technically never use type hints. Caveat emptor. We don't recommend this strategy at all!

Always

You can choose the type hint here. Salat now defaults to "_t" but for compatibility with pre-1.9.0 data, use "_typeHint".

package foo

  import com.novus.salat._

  package object when_necessary_context {

    implicit val ctx = new Context {
        val name = "When-Necessary-Context"

        override val typeHintStrategy = StringTypeHintStrategy(when = TypeHintFrequency.Always,
            typeHint = "_typeHint")

    }
  }

When necessary

This is the default behaviour. Just import the Salat global context to get what you want.

import com.novus.salat.global._

Never

package bar

  import com.novus.salat._

  package object never_typehint_context {

    implicit val ctx = new Context {
        val name = "Never-TypeHint-Context"

        override val typeHintStrategy = NeverTypeHint

    }
  }

How can I globally customise type hints?

See custom Salat context for more information.

Clone this wiki locally