-1

I've spent so much time and still don't understand what the problem here. So I have a collection that data looks like:

{ "_id" : "someId", "employment" : { "data" : [ 
    { "retrieved" : { "$date" : "2015-03-12T14:39:41.214Z"} , "value" : { "city" : "someSity" , "fromMonth" : 0 , "name" : "someName" , "fromYear" : 2011 , "toMonth" : 0 , "speciality" : "someSpeciality"}},
    { "retrieved" : { "$date" : "2015-03-12T14:39:41.214Z"} , "value" : { "city" : "someSity" , "fromMonth" : 7 , "name" : "someName" , "fromYear" : 2013 , "toMonth" : 7 , "toYear" : 2014 , "speciality" : "someSpeciality"}},
    { "retrieved" : { "$date" : "2015-03-12T14:39:41.214Z"} , "value" : { "city" : "someSity" , "fromMonth" : 10 , "name" : "someName" , "fromYear" : 2010 , "toMonth" : 10 , "toYear" : 2010 , "speciality" : "someSpeciality"}}
    { "retrieved" : { "$date" : "2015-03-12T14:39:41.214Z"} , "value" : { "fromMonth" : 2 , "name" : "someName" , "fromYear" : 2007 , "toMonth" : 2 , "toYear" : 2010 , "speciality" : "someSpeciality"}}
]}}

also I have SalatDAO for that collection:

object ProfileDAO extends SalatDAO[Profile, ObjectId](
  collection = MongoFactory.getDB("profiles"))

and ofcourse a bunch of case class:

case class Profile(
  @Key("_id") id: String,
  employment: Option[ListField[Employment]]

case class ListField[T](
  data: List[Value[T]])

case class Value[T](
  value: Option[T],
  retrieved: Option[Instant],
  deleted: Option[Instant])

and finally Employment class:

case class Employment(
   name: Option[String],
   country: Option[String],
   city: Option[String],
   fromMonth: Option[Int],
   toMonth: Option[Int],
   fromYear: Option[Int],
   toYear: Option[Int],
   speciality: Option[String]
   )

Byt when I try do something like this:

ProfileDAO.findAll().take(20).map(
    profile => profile.employment.map(
        employment => employment.data.map(
            employmentData => employmentData.value.name)))
.foreach(println)

I get Exception: com.mongodb.BasicDBObject cannot be cast to com....Employment Only one idea I have - some data in DBCollection don't match with Employment class, but there is Option[] evrywhere, so...

invis
  • 1,078
  • 2
  • 14
  • 26

1 Answers1

0

Go to where it's blowing up and print the _id value of the document that's failing to deserialize?

prasinous
  • 798
  • 3
  • 6
  • for example: exception in: Value({ "fromMonth" : 0 , "toMonth" : 0 , "speciality" : "someSpeciality"},Some(Wed Mar 11 18:42:56 MSK 2015),None) you can see that ProfileDAO deserialize `retrieved: Option[Instant]` and `deleted: Option[Instant]` fields, but not `value: Option[T]` field – invis Jun 30 '15 at 08:40
  • `val employmentColl = profiles.filter(pr => pr.employment.nonEmpty).map(pr => pr.employment.get) val empValues = employmentColl.flatMap(emp => emp.data) //to get rid of ListField[] for(value <- empValues){ try { println("city: " + value.value.get("city")) //works, because value here is BasicDBObject println("city: " + value.value.city) //throw Exception } catch { case e: ClassCastException => println("exception in: " + value) } }` I tried Employment to extends BasicDBObject - nothing changed – invis Jun 30 '15 at 10:11
  • For me it looks like a bug in Salat – invis Jun 30 '15 at 10:24
  • Can you unwind this nest of types and remove the parameterized classes `Value` and `ListField`? They don't add very much and they might be obscuring some other bug. Extending `BasicDBObject` doesn't help anything. You've got a lot going on here, and your first goal is to get _one_ record to successfully deserialize. (The way these replies mash your code into unreadable blocks makes it hard to help!) If `Employment` deserializes successfully after removing `Value` and `ListField`, try adding them back in one by one. If that fails, make a simple GitHub project that demonstrates the error. – prasinous Jun 30 '15 at 13:48
  • But I need `Value` and `ListField` cause of structure of Data inside, look at original question. – invis Jun 30 '15 at 15:22
  • I read somewhere that this error maybe cause of using scala.List. So I change `ListField` row `data: List[Value[T]]` to `data: java.util.ArrayList[Value[T]]` and what? Now I have the same exception, but on one step above! `BasicDBObject cannot be cast to com.....Value` Before that I get exception on casting object inside `Value` (like I wrote in first post). Why this happens? I think I am on the right way – invis Jun 30 '15 at 19:57
  • WOW! I create new DBCollection and insert one Row with mine ProfileDao, and this is what I get when `db.find()`: `{ "_id" : "someId", "employment" : { "data" : [ { "value" : [ "Alex", "England", "London" ], "retrieved" : "some time here" }, { "value" : [ "Sasha", "England", "London" ], "retrieved" : "some time here" } ] } }` So as you can see `Employment` writes as LIST!!! And when I try to deserialize is I get an Exception... Why is this?? – invis Jun 30 '15 at 21:16
  • It's serializing as a list because neither Salat nor mongo-java-driver have any idea what to do with it. If you cannot eliminate those two classes, see if it serializes correctly if you parameterize them. – prasinous Jul 01 '15 at 15:59
  • Also, could we _please_ take this off SO comments? Unfortunately the code block formatting is *extremely difficult* to read. Please create a sample GitHub project demonstrating your error. We can post back here or edit the original answer when your problem is fixed. – prasinous Jul 01 '15 at 16:04