4

Based on the activator-akka-cassandra example I'm creating my own app which will save data into cassandra.

I defind a data model as follows

import play.api.libs.json.Json

case class Location(lat: Double, long: Double)
object Location {
  implicit def toLocation(lat: Double, long: Double) = Location(lat, long)
}

case class LocationWithTime(location: Location, time: Long)
object LocationWithTime {
  implicit def toLocationWithTime(location: Location, time: Long) = LocationWithTime(location, time)
}

case class Ping(pingUuid: String, senPhoneNumber: String, recPhoneNumber: Set[String], locationWithTime: LocationWithTime)
object Ping {
  implicit val LocationFormat = Json.format[Location]
  implicit val LocationWithTimeFormat = Json.format[LocationWithTime]
  implicit val PingFormat = Json.format[Ping]
}

Unfortunately the code which is supposed to save the data:

def insertPing(ping: Ping): Unit =
    session.executeAsync(insertPing.bind(ping.pingUuid, ping.senPhoneNumber, ping.recPhoneNumber,
      ping.locationWithTime.location.lat, ping.locationWithTime.location.long, ping.locationWithTime.time))

does not not compile and return the error

Error:(24, 38) the result type of an implicit conversion must be more specific than AnyRef
      ping.locationWithTime.location.lat, ping.locationWithTime.location.long, ping.locationWithTime.time))
                                 ^

The case classes in the example data model extend AnyVal. Based on this I would guess that something similar would do the trick in my case too, but I can't do that because ValueClasses can have only one parameter. How do I solve this?

Community
  • 1
  • 1
Lukasz
  • 2,257
  • 3
  • 26
  • 44

1 Answers1

7

Although I'm not familiar with Cassandra, I think your problem is that bind takes Java Objects (i.e. AnyRefs) and lat, is a scala.Double (i.e. a Java double), which is not an AnyRef.

You can make it such by wrapping your scala.Doubles in java.lang.Double.

insertPing.bind(ping.pingUuid, ping.senPhoneNumber, ping.recPhoneNumber, new java.lang.Double(ping.locationWithTime.location.lat), new java.lang.Double(ping.locationWithTime.location.long), ping.locationWithTime.time)
badcook
  • 3,699
  • 14
  • 25
  • Your answer is correct, however you forgot a new before java.lang.Double. So it should be `session.executeAsync(insertPing.bind(ping.pingUuid, ping.senPhoneNumber, ping.recPhoneNumber, new java.lang.Double(ping.locationWithTime.location.lat), new java.lang.Double(ping.locationWithTime.location.long), new java.lang.Long(ping.locationWithTime.time)))` – Lukasz Apr 17 '16 at 19:35
  • This is what I get for not checking this with a compiler. Editing the answer now. – badcook Apr 17 '16 at 19:37