使用Scala的Datastax Cassandra驱动程序 - 未找到编解码器

时间:2018-01-07 13:59:32

标签: scala cassandra codec datastax-java-driver cassandra-3.0

  1. Datastax驱动程序Cassandra版本:3.3.2
  2. Scala版本:2.12.4
  3. 我正在为Cassandra的datastax java驱动程序中的mappingmanager创建一个scala包装器。

    为此,我有以下简单的表格:

    CREATE TABLE todo (
        id UUID,
        title TEXT,
        completed boolean,
        PRIMARY KEY((id), completed, title)
    )  WITH CLUSTERING ORDER BY (completed ASC, title ASC);
    

    createAsync,saveAsync和deleteAsync函数现在运行正常。现在我想实现更通用的executeAsync功能。因此,我有以下代码:

    private def executeAsync(query: String, params: Any*): Future[ResultSet] = {
        params match {
          case Seq() =>
            session.executeAsync(query) // had a problem with empty params varargs
          case _ =>
            prepareAsync(query).map(preparedStatement =>
              preparedStatement.bind(
                params
                  .map(x => {
                    println(x) // correctly prints the param
                    x.asInstanceOf[Object]
                  })
              )
            ).flatMap(x => {
              println("here") // never gets printed
              session.executeAsync(x)
            })
        }
      }
    
      private def prepareAsync(query: String): Future[PreparedStatement] = {
        session.prepareAsync(query)
      }
    

    以下查询正确检索值:

    val future: Future[List[TodoCassandra]] = customMappingManager.executeQueryAsync("SELECT * FROM todo;")
        future.onComplete {
          case Success(x) =>
            println(x)
        }
    

    以下示例:

    val future: Future[List[TodoCassandra]] = customMappingManager.executeQueryAsync("INSERT INTO todo (id, title, completed) VALUES (uuid(), ?, ?)", "prepared statement test", false)
    
    val future: Future[List[TodoCassandra]] = customMappingManager.executeQueryAsync("INSERT INTO todo (id, completed, title) VALUES (uuid(), ?, ?)", false, "prepared statement test")
    
    val future: Future[List[TodoCassandra]] = customMappingManager.executeQueryAsync("SELECT * FROM todo WHERE id = ?", "a8a6da8b-3d0e-40b3-99e5-fe2f664f50d0")
    

    结果:

    1. 找不到请求操作的编解码器:[varchar< - > scala.collection.mutable.ArrayBuffer])(类scala.util.Failure)
    2. 找不到请求操作的编解码器:[boolean< - > scala.collection.mutable.ArrayBuffer])(类scala.util.Failure)
    3. 找不到所请求操作的编解码器:[uuid< - > scala.collection.mutable.ArrayBuffer])(类scala.util.Failure)
    4. 为什么它始终从scala.collection.mutable.ArrayBuffer'转换'? 可以解决这个问题的解决方案是什么?

1 个答案:

答案 0 :(得分:0)

使用Querying Cassandra from Scala教程时,我遇到了类似的问题。

错误是什么

您的preparedStatement.bind方法与文章中的方法类似,但也有相同的缺陷。也就是说,在Seq[Object]期间,您将Any项目中的每一项投放到Object后传递var-args。 这似乎失败了。

修复

简单的解决方法是,将此序列作为def execute(statement: Future[PreparedStatement], params: Any*) (implicit executionContext: ExecutionContext, session: Session): Future[ResultSet] = { val p = params.map(_.asInstanceOf[Object]) statement .map(_.bind(p: _*)) .flatMap(session.executeAsync(_)) } 传递,就像Java方法实际期望的那样。

代码:

Sub Test()
    Dim filts As Variant
    With Worksheets("Sheet2")
        filts = Application.Transpose(.Range("A2", .Cells(.Rows.Count, 1).End(xlUp)).Value)
    End With

    With Worksheets("Sheet1").Range("A1").CurrentRegion
        .AutoFilter Field:=2, Criteria1:=filts, Operator:=xlFilterValues
        If Application.WorksheetFunction.Subtotal(103, .Columns(1)) > 1 Then .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0).SpecialCells(xlCellTypeVisible).Copy Worksheets("Output").Range("A1")
        .Parent.AutoFilterMode = False
    End With
End Sub