2016-03-23 8 views
0

Ich habe ein Problem mit Slick. Es sieht aus wie nach der Verwendung von Scala ist nicht mehr eine statisch typisierte Sprache :)ClassCastException bei Verwendung von Slick und Sql Server gespeicherte Prozedur

Ich benutzte Slick, um eine gespeicherte SqlServer-Prozedur aufzurufen, die einige Werte zurückgeben sollte (und es tut, wenn ich die Prozedur direkt in meinem SQL-Client aufrufen). Leider, wie Sie unten sehen können, habe ich ein val mit Typ Option [ProcessUserRoleDto], mit ProcessUserRoleDto ist nur eine gewöhnliche Fall-Klasse, die tatsächlich Wert von Einige (1) und die '1' ist vom Typ java.lang.Integer. Wie ist das möglich? Haben Sie Ideen, wie Sie dieses Problem lösen können?

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 
} 

Antwort

0

Die gespeicherte Prozedur führte eine Insert-Anweisung und dann eine Select-Anweisung aus. Es stellt sich heraus, dass es den JDBC-Treiber verwechselte, weil die Einfügung die Anzahl der geänderten Datensätze zurückgab und das Hinzufügen von "SET NOCOUNT ON" zur gespeicherten Prozedur das beendete (https://stackoverflow.com/a/4809815/1185138).

Immer noch glatte, verpatzte Typen anstatt eine nette Fehlermeldung darüber zu wiederholen.

Verwandte Themen