Scala 尝试按UUID进行筛选时出错-Slick

Scala 尝试按UUID进行筛选时出错-Slick,scala,slick,Scala,Slick,我正在尝试使用以下内容筛选我的表: val applicationId = ... val application = Applications.filter(_.id === applicationId).first 其中id和applicationId是UUID 我遇到了一个错误: scala.slick.SlickException: UUID does not support a literal representation 我发现我需要使用bind: // val applicat

我正在尝试使用以下内容筛选我的表:

val applicationId = ...
val application = Applications.filter(_.id === applicationId).first
其中
id
applicationId
是UUID

我遇到了一个错误:

scala.slick.SlickException: UUID does not support a literal representation
我发现我需要使用
bind

// val applicationId is a UUID
val application = Applications.filter(_.id === applicationId.bind).first
但是,这会引发异常

java.util.NoSuchElementException: Invoker.first
即使我使用我知道在表中的UUID进行查询

这是Slick正在生成的
selectStatement
。我不知道为什么它不包括UUID

select x2."Id" from "Application" x2 where x2."Id" = ?

我今天一直在努力解决这个问题。我不知道我是否有一个好的解决方案,但我可以给出一些选择

修补光滑的驱动程序以允许平等测试 我使用的是MySQL,该数据库支持以字符串形式发送字节数据的语法:

mysql> desc user;
+---------------+--------------+------+-----+---------+-------+
| Field         | Type         | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| user_uuid     | binary(16)   | NO   | PRI | NULL    |       |
| email         | varchar(254) | NO   | UNI | NULL    |       |
| display_name  | varchar(254) | NO   |     | NULL    |       |
| password_hash | varchar(254) | YES  |     | NULL    |       |
+---------------+--------------+------+-----+---------+-------+
4 rows in set (0.01 sec)

mysql> select * from user where user_uuid = x'e4d369040f044b6e9561765c356907d3';
+------------------+-----------------+--------------+---------------+
| user_uuid        | email           | display_name | password_hash |
+------------------+-----------------+--------------+---------------+
| ????????????     | foo@example.com | Foo          | NULL          |
+------------------+-----------------+--------------+---------------+
1 row in set (0.00 sec)
要显示UUID是正确的,请执行以下操作:

mysql> select hex(user_uuid), email, display_name from user where user_uuid = x'e4d369040f044b6e9561765c356907d3';
+----------------------------------+-----------------+--------------+
| hex(user_uuid)                   | email           | display_name |
+----------------------------------+-----------------+--------------+
| E4D369040F044B6E9561765C356907D3 | foo@example.com | Foo          |
+----------------------------------+-----------------+--------------+
在此基础上,MySQLDriver.scala(1.0.1版)的以下补丁运行良好:

$ git diff
diff --git a/src/main/scala/scala/slick/driver/MySQLDriver.scala b/src/main/scala/scala/slick/driver/
index 84a667e..1aa5cca 100644
--- a/src/main/scala/scala/slick/driver/MySQLDriver.scala
+++ b/src/main/scala/scala/slick/driver/MySQLDriver.scala
@@ -174,9 +174,15 @@ trait MySQLDriver extends ExtendedDriver { driver =>
       }
     }

+    import java.util.UUID
+
     override val uuidTypeMapperDelegate = new UUIDTypeMapperDelegate {
       override def sqlType = java.sql.Types.BINARY
       override def sqlTypeName = "BINARY(16)"
+
+    override def valueToSQLLiteral(value: UUID): String =
+      "x'"+value.toString.replace("-", "")+"'"
     }
   }
 }
有了它,您可以编写如下代码:

def findUserByUuid(uuid: UUID): Option[UserRecord] = db.withSession {
  // Note: for this to work with slick 1.0.1 requires a tweak to MySQLDriver.scala
  // If you don't, the "===" in the next line will fail with:
  // "UUID does not support a literal representation".
  val query = (for (u <- UserRecordTable if u.uuid === uuid) yield u)
  query.firstOption
}
def finduserbyuid(uuid:uuid):选项[UserRecord]=db.withSession{
//注意:为了使它与slick 1.0.1一起工作,需要对MySQLDriver.scala进行调整
//否则,下一行中的“==”将失败,原因是:
//“UUID不支持文字表示”。
val查询=(对于(u)
import UuidHelper

implicit object SetUUID extends SetParameter[UUID] {
  def apply(v: UUID, pp: PositionedParameters) { pp.setBytes(UuidHelper.toByteArray(v)) }
}
implicit val getUserRecordResult = GetResult(r => 
  UserRecord(UuidHelper.fromByteArray(r.nextBytes()), r.<<, r.<<, r.<<)
)

val userByUuid = StaticQuery[UUID, UserRecord] + "select * from user where user_uuid = ?"
val user = userByUuid(user.uuid).first
// do what you want with user.
implicit val getUserRecordResult = GetResult(r => UserRecord(UuidHelper.fromByteArray(r.nextBytes()), r.<<, r.<<, r.<<))

val uuid = user.uuid.toString.replace("-", "")
val userByUuid = StaticQuery.queryNA[UserRecord](s"select * from user where user_uuid = x'$uuid'")
val user = userByUuid().first