I am using Play 2.1.4 against a postgresql db. In the postgresql db, I am using uuid as my pk datatype, which correlates to java.util.UUID. The SqlParser.getT function in anorm doesn't have an implicit extractor for java.util.UUID. That makes sense, because I don't think many people use it; however, I can't seem to find instructions on how I can add one. Does anyone know how to add an additional implicit extractor to anorm.SqlParser in Play?
The error I am getting is below:
could not find implicit value for parameter extractor: anorm.Column[java.util.UUID]
I'm really new to Scala and Play, so if my approach is completely wrong, please let me know, but I'd really like to be able to do something like what you see below.
case class App(appId: UUID, appName: String, appServerName: String,
appComponent: String, appDescription: String,
appDateCreated: DateTime, appDateModified: DateTime,
appValidated: Boolean)
val app = {
get[UUID]("app_id") ~
get[String]("app_name") ~
get[String]("app_server_name") ~
get[String]("app_component") ~
get[String]("app_description") ~
get[java.util.Date]("app_date_created") ~
get[java.util.Date]("app_date_modified") ~
get[Boolean]("app_validated") map {
case id ~ name ~ serverName ~ component ~ description ~ dateCreated ~
dateModified ~ validated => App(id, name, serverName, component,
description, new DateTime(dateCreated.getTime),
new DateTime(dateModified.getTime), validated)
}
}
def all(): List[App] = DB.withConnection { implicit conn =>
SQL("SELECT * FROM apps").as(app *)
}
Here is a simplified variation of the @r.piesnikowski answer for a JDBC driver that returns java.util.UUID, like PostgreSQL does:
/**
* Implicit conversion from UUID to Anorm statement value
*/
implicit def uuidToStatement = new ToStatement[UUID] {
def set(s: java.sql.PreparedStatement, index: Int, aValue: UUID): Unit = s.setObject(index, aValue)
}
/**
* Implicit conversion from Anorm row to UUID
*/
implicit def rowToUUID: Column[UUID] = {
Column.nonNull[UUID] { (value, meta) =>
value match {
case v: UUID => Right(v)
case _ => Left(TypeDoesNotMatch(s"Cannot convert $value:${value.asInstanceOf[AnyRef].getClass} to UUID for column ${meta.column}"))
}
}
}
Maybe this post will be helpfull. (Used in my project. Working fine)
/**
* Attempt to convert a SQL value into a UUID
*
* @param value value to convert
* @return UUID
*/
private def valueToUUIDOption(value: Any): Option[UUID] = {
try {
valueToByteArrayOption(value) match {
case Some(bytes) => Some(UUIDHelper.fromByteArray(bytes))
case _ => None
}
}
catch {
case e: Exception => None
}
}
/**
* Implicit conversion from UUID to anorm statement value
*/
implicit def uuidToStatement = new ToStatement[UUID] {
def set(s: java.sql.PreparedStatement, index: Int, aValue: UUID): Unit = s.setObject(index, aValue)
}
/**
* Implicit converstion from anorm row to uuid
*/
implicit def rowToUUID: Column[UUID] = {
Column.nonNull[UUID] { (value, meta) =>
val u = UUID.fromString(value.toString)
val MetaDataItem(qualified, nullable, clazz) = meta
valueToUUIDOption(value) match {
case Some(uuid) => Right(uuid)
case _ => Left(TypeDoesNotMatch("Cannot convert " + value + ":" + value.asInstanceOf[AnyRef].getClass + " to UUID for column " + qualified))
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With