1

I've been using Salat within a Play2 webapp for MongoDB interaction (via Leon Radley's neat SBT plugin). Works great, however as we have many case class DTOs due to nesting (to mirror nested JSON/BSON model definitions) we wanted to neatly define the nested case class DTOs in a companion object of the base model type.

This prevents namespace clashes in the soup of case class DTOs that have proliferated in our Salat data access layer. e.g., we define a "Description" case class, but it is redefined for different model objects so we wanted a neat way to namespace it. We tried using a companion Object for this purpose, like in this little snippet/example:

package models.mongo

import com.novus.salat._
import com.mongodb.casbah.Imports._
import se.radley.plugin.salat._

case class TestSalatDto(
  id: ObjectId = new ObjectId,
  title: String,
  description: TestSalatDto.Description)

object TestSalatDto {
  case class Description(
    brief: String,
    full: String)
}

This all compiles beautifully, but fails at runtime with a com.novus.salat.util.ToObjectGlitch: argument type mismatch during unmarshalling from Mongo.

If we simply switch the companion object definition into a package defintion (a slightly messier way of encapsulating the DTO soup) then all runs fine (the unmarshalling works a treat).

I'm confused as to why declaring the case classes within an Object fails at runtime; is there a trick to defining case classes (Salat DTOs) within an Object?

Bogdan
  • 5,368
  • 9
  • 43
  • 62
DaveE
  • 11
  • 1
  • Do you still get the error if you import TestSalatDto._, and then use Description directly? Maybe it needs to be in scope? – nairbv Feb 14 '13 at 01:58

2 Answers2

0

I would not try to have a case class and a Singleton of the same name in the same source. The case class creates it's own compation object wich conflicts with your Singleton. My solution would be without companion object, just the class TestSalatDtoDescription (whatever that is)

Arne
  • 7,921
  • 9
  • 48
  • 66
  • Hey, I think declaring a companion object in the same source as the case class is a-ok, Scala just neatly merges what you declare into the default companion that is compiler generated for the case class. – DaveE Apr 24 '12 at 12:43
  • but they are still a conflict an my brain. Maybe the compiler does something with it, but it might be unpredictable, at least as long as you don't know what the compiler actually does with it. – Arne Apr 25 '12 at 08:27
0

your issue here is that Salat does not currently support nested classes.

Doesn't work:

object TestSalatDto {
  case class Description(
  brief: String,
  full: String)
}

Works fine:

case class Description( /* etc etc */)
case class TestSalatDto(description: Description, /* etc etc*/)
prasinous
  • 798
  • 3
  • 6