Search code examples
scalasalat

Salat serialisation error


I'm currently having issues with Salat. Hope you guys can help me!

Here's the case class that is driving me crazy:

object UserDAO extends SalatDAO[User, ObjectId](
  collection = DB("users") //Returns the "users" MongoCollection
)

case class User(
  _id: ObjectId = new ObjectId,
  firstName: String,
  lastName: String,
  screenName: String,
  phoneNumber: PhoneNumber,
  validated: Boolean = false)

PhoneNumber is an instance of type com.google.i18n.phonenumbers.Phonenumber$PhoneNumber (I'm using libphonenumber)

This is my custom transformer:

class PhoneNumberTransformer extends CustomTransformer[PhoneNumber, String] {
  val phoneNumberUtils = PhoneNumberUtil.getInstance()
  def deserialize(b: String) = phoneNumberUtils.parse(b, "UK")
  def serialize(a: PhoneNumber) = phoneNumberUtils.format(a, PhoneNumberFormat.INTERNATIONAL)
}

This is my custom context:

package object model {

  implicit val ctx = new Context {
    val name = "Custom Salat Context"
  }

  ctx.registerCustomTransformer(new PhoneNumberTransformer)

}

If I try to insert a new User document using UserDAO, I get this exception:

project java.lang.IllegalArgumentException: can't serialize class com.google.i18n.phonenumbers.Phonenumber$PhoneNumber
project     at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:284)
project     at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:185)
project     at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:131)
project     at com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:33)
[...] 

Any idea on how to solve this? Thanks


Solution

  • Salat developer here. I'm not familiar with libphonenumber but this is most likely breaking down because it looks like you're trying to serialize an inner class.

    Something to try. If you copy pasted the PhoneNumber class to the top level of a local package (not inside an object, trait, or class), extending the relevant class/interface that bring the i18n goodness, and changed the type param to point at this class instead, does it work?

    If so, the problem is that Salat doesn't support inner classes. If not, we'll have to look further.