使用 slick 和 Sql 服务器存储过程时出现 ClassCastException
ClassCastException when using slick and Sql Server stored procedure
我对 slick 有疑问。使用它之后,scala 似乎不再是一种静态类型的语言:)
我使用 slick 调用了一个应该 return 一些值的 SqlServer 存储过程(当我在我的 SQL 客户端中直接调用该过程时它确实如此)。不幸的是,正如您在下面看到的,结果是我有一个类型为 Option[ProcessUserRoleDto] 的 val,其中 ProcessUserRoleDto 只是一个普通的案例 class,实际上它的值是Some(1) 并且“1”的类型为 java.lang.Integer。这怎么可能?您有解决此问题的想法吗?
case class ProcessUserRoleDto(
processUserRoleId: Int,
processUserId: Int,
processRoleId: Int,
dataCollectionId: Int,
recognizingInstanceId: Int,
processRoleName: String,
dataCollectionName: String,
recognizingInstanceName: String,
isActive: Boolean)
def assign(dto: ProcessUserRoleAssignDto): Future[Option[ProcessUserRoleDto]] = {
val db = implicitly[SQLServerDriver.backend.DatabaseDef]
val sql = sql"exec EVO.spProcessUserRoleAssignToRecognizingInstance ${dto.ProcessUser_ID}, ${dto.ProcessRole_ID}, ${dto.RecognizingInstance_ID}"
implicit val registerProcessUserResult = GetResult { r =>
ProcessUserRoleDto(r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<)
}
val resultFut: Future[Option[ProcessUserRoleDto]] = db
.run(sql.as[ProcessUserRoleDto])
.map(_.headOption)
val singleResult: Option[ProcessUserRoleDto] = Await.result(resultFut, 10 seconds)
println(s"singleResult = $singleResult")
// in runtime result was: Some(1)
// WTF ?!?
println(s"class inside Some() = ${singleResult.get.getClass.getCanonicalName}")
// in runtime result is: java.lang.Integer
println(s"Option[Class] = ${singleResult.map(_.getClass.getCanonicalName)}")
// here exception is thrown: java.lang.ClassCastException: java.lang.Integer cannot be cast to ProcessUserRoleDto
}
存储过程正在执行插入语句,然后执行 select 语句。我发现它混淆了 JDBC 驱动程序,因为插入返回修改记录的数量并且将 "SET NOCOUNT ON" 添加到存储过程停止了 ().
不过,slick 悄悄地搞砸了类型,而不是返回一个很好的错误消息..
我对 slick 有疑问。使用它之后,scala 似乎不再是一种静态类型的语言:)
我使用 slick 调用了一个应该 return 一些值的 SqlServer 存储过程(当我在我的 SQL 客户端中直接调用该过程时它确实如此)。不幸的是,正如您在下面看到的,结果是我有一个类型为 Option[ProcessUserRoleDto] 的 val,其中 ProcessUserRoleDto 只是一个普通的案例 class,实际上它的值是Some(1) 并且“1”的类型为 java.lang.Integer。这怎么可能?您有解决此问题的想法吗?
case class ProcessUserRoleDto(
processUserRoleId: Int,
processUserId: Int,
processRoleId: Int,
dataCollectionId: Int,
recognizingInstanceId: Int,
processRoleName: String,
dataCollectionName: String,
recognizingInstanceName: String,
isActive: Boolean)
def assign(dto: ProcessUserRoleAssignDto): Future[Option[ProcessUserRoleDto]] = {
val db = implicitly[SQLServerDriver.backend.DatabaseDef]
val sql = sql"exec EVO.spProcessUserRoleAssignToRecognizingInstance ${dto.ProcessUser_ID}, ${dto.ProcessRole_ID}, ${dto.RecognizingInstance_ID}"
implicit val registerProcessUserResult = GetResult { r =>
ProcessUserRoleDto(r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<)
}
val resultFut: Future[Option[ProcessUserRoleDto]] = db
.run(sql.as[ProcessUserRoleDto])
.map(_.headOption)
val singleResult: Option[ProcessUserRoleDto] = Await.result(resultFut, 10 seconds)
println(s"singleResult = $singleResult")
// in runtime result was: Some(1)
// WTF ?!?
println(s"class inside Some() = ${singleResult.get.getClass.getCanonicalName}")
// in runtime result is: java.lang.Integer
println(s"Option[Class] = ${singleResult.map(_.getClass.getCanonicalName)}")
// here exception is thrown: java.lang.ClassCastException: java.lang.Integer cannot be cast to ProcessUserRoleDto
}
存储过程正在执行插入语句,然后执行 select 语句。我发现它混淆了 JDBC 驱动程序,因为插入返回修改记录的数量并且将 "SET NOCOUNT ON" 添加到存储过程停止了 ().
不过,slick 悄悄地搞砸了类型,而不是返回一个很好的错误消息..