Драйвер Datastax Cassandra со Scala — кодеки не найдены

  1. Версия драйвера Datastax Cassandra: 3.3.2
  2. Скала версия: 2.12.4

Я играю с созданием оболочки scala для менеджера карт в java-драйвере datastax для Cassandra.

Для этого у меня есть следующая простая таблица:

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. Кодек не найден для запрошенной операции: [логический ‹-> scala.collection.mutable.ArrayBuffer]) (класса scala.util.Failure)
  3. Кодек не найден для запрошенной операции: [uuid ‹-> scala.collection.mutable.ArrayBuffer]) (класса scala.util.Failure)

Почему он всегда «конвертируется» из scala.collection.mutable.ArrayBuffer? Какое может быть решение, чтобы исправить это?


person xDs    schedule 07.01.2018    source источник


Ответы (1)


Я столкнулся с проблемой, похожей на вашу, при использовании запроса Cassandra из Scala учебник.

В чем ошибка

Ваш метод executeAsync выглядит так же, как и в статье, и имеет тот же дефект. А именно, во время preparedStatement.bind вы передаете Seq[Object] после преобразования каждого из Any элементов в Object. И это, похоже, не удается.

Исправить

Простое исправление состоит в том, чтобы передать эту последовательность как var-args, как на самом деле ожидает метод Java.

Код:

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(_))
}
person Atais    schedule 06.04.2018