Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automated mapping and "implicit conversion must be more specific then Any Ref" error

Tags:

scala

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?

like image 685
Lukasz Avatar asked Mar 12 '23 14:03

Lukasz


1 Answers

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)
like image 154
badcook Avatar answered Mar 16 '23 04:03

badcook