ISODate issue in ReactiveMongo

299 views
Skip to first unread message

chao chu

unread,
Sep 11, 2015, 4:20:47 AM9/11/15
to ReactiveMongo - http://reactivemongo.org
Hi,

In other language's drivers (like Java and c#), the Date (java.util.Date) and DateTime in c# will be written into Mongo as ISODate.

However, in ReactiveMongo, a jave.util.Date will be written as a NumberLong (the epoch long value). This means data written by different drivers will not be compatible. 

And in ReactiveMongo, it will read a ISODate from mongo as a JsObject("$date": JsNumber(...)) (with a single '$date' field).

I think, for reading, it's fine we can work around this by constructing the date object from the JsObject. The bigger problem is that if both will do both reads and writes, the data will not be compatible. Is there any solution for this? Thanks!

Cédric Chantepie

unread,
Sep 11, 2015, 6:56:35 AM9/11/15
to ReactiveMongo - http://reactivemongo.org
What do you mean by "in ReactiveMongo, a java.util.Date will be written as a NumberLong"? See https://github.com/ReactiveMongo/ReactiveMongo/blob/master/bson/src/test/scala/Handlers.scala#L126

chao chu

unread,
Sep 12, 2015, 6:28:30 AM9/12/15
to reacti...@googlegroups.com
I am sorry for the confusion, I realized it is related with how play-json does the serialization/deserilization:

case class User(id: Int, name: String, birth: java.util.Date)

object User {
implicit object UserWrites extends OWrites[User] {
def writes(user: User): JsObject = Json.obj(
"_id" -> user.id,
"name" -> user.name,
// the implicit conversion for Date will be converted to epoch long (NumberLong in Mongo)
"birth" -> user.birth
)
}

implicit object UserReads extends Reads[User] {
def reads(json: JsValue): JsResult[User] = json match {
case obj: JsObject => try {
val id = (obj \ "_id").as[Int]
val name = (obj \ "name").as[String]
// assuming 'birth' is stored in mongo as a ISODate, we wouldn't be able to read a Date directly
// since the JsObject got here is JsObject("$date": $the_epoch_long).
val birth = (obj \ "birth").as[java.util.Date]

JsSuccess(User(id, name, birth))
} catch {
case e: Exception => JsError(e.getStackTraceString)
}
case _ => JsError("error!")
}
}
}

How can we bridge the gap in this case?

On Fri, Sep 11, 2015 at 6:56 PM, Cédric Chantepie <chantep...@gmail.com> wrote:
What do you mean by "in ReactiveMongo, a java.util.Date will be written as a NumberLong"? See https://github.com/ReactiveMongo/ReactiveMongo/blob/master/bson/src/test/scala/Handlers.scala#L126

--
You received this message because you are subscribed to a topic in the Google Groups "ReactiveMongo - http://reactivemongo.org" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/reactivemongo/YsFKUHMt0DY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to reactivemong...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
ChuChao

Cédric Chantepie

unread,
Sep 13, 2015, 5:04:17 AM9/13/15
to ReactiveMongo - http://reactivemongo.org
What's the issue there?

chao chu

unread,
Sep 13, 2015, 11:49:19 AM9/13/15
to reacti...@googlegroups.com
Hi Cedric,

Never mind, I was trying to find a compatible way to implement the OWrites and Reads for User (which has a java.util.Date memeber), now I found that I should do sth like below:

in OWrites:
...
"birth" -> BSONDateTime(user.birth.getTime)

in Reads:

...
val birth = new java.util.Date((obj \ "birth").as[BSONDateTime].value)

On Sun, Sep 13, 2015 at 5:04 PM, Cédric Chantepie <chantep...@gmail.com> wrote:
What's the issue there?


--
You received this message because you are subscribed to a topic in the Google Groups "ReactiveMongo - http://reactivemongo.org" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/reactivemongo/YsFKUHMt0DY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to reactivemong...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
ChuChao
Reply all
Reply to author
Forward
0 new messages