Datastax java驱动程序,将scala集合转换为java错误

pla*_*bre 3 scala cassandra datastax-java-driver

我正在尝试将Scala Map(我正在尝试转换为java.util.Map)存储到cassandra 2.1.8中.

数据结构如下所示:

Map[String -> Set[Tuple[String, String, String]]]
Run Code Online (Sandbox Code Playgroud)

我创建了如下表:

CREATE TABLE mailing (emailaddr text PRIMARY KEY, totalmails bigint, emails map<text, frozen<set<tuple<text, text, text>>>>);
Run Code Online (Sandbox Code Playgroud)

我首先尝试将Set转换为java Set:

def emailsToCassandra(addr: emailAddress, mail: MailContent, number: Int) = {
println("Inserting emails into cassandra")

mail.emails.foreach(result =>

  setAsJavaSet(result._2)
)
Run Code Online (Sandbox Code Playgroud)

然后我构建查询并尝试将Map转换为java Map:

val query = QueryBuilder.insertInto("emails", "mailing")
                        .value("emailAddr", addr.toString())
                        .value("totalmails", number)
                        .value("emails", mapAsJavaMap(mail.emails))
session.executeAsync(query)
Run Code Online (Sandbox Code Playgroud)

我回来了:

java.lang.IllegalArgumentException: Value 1 of type class scala.collection.convert.Wrappers$MapWrapper does not correspond to any CQL3 type
Run Code Online (Sandbox Code Playgroud)

我也试过这样做:

val lol = mail.emails.asInstanceOf[java.util.Map[String, java.util.Set[Tuple3[String, String, String]]]]
Run Code Online (Sandbox Code Playgroud)

哪个没用

先感谢您

And*_*ert 5

在这里你需要克服一些事情:

  1. 将映射转换为java.util.Map类型.(您已经通过使用mapAsJavaMap来解决这个问题)
  2. 将Set [Tuple3]转换为java.util.Set类型.
  3. 将Tuple3转换为TupleValue.

不幸的是,驱动程序(java.lang.IllegalArgumentException: Value 1 of type class scala.collection.convert.Wrappers$MapWrapper does not correspond to any CQL3 type)返回的错误是误导性的,因为Map类型在您的代码中正确转换,但Tuple3类型最终是它遇到问题.我打开JAVA-833跟踪这个.

我正在假设MailContent是什么,但这里有一些代码可以让事情发挥作用.繁重的主要逻辑是emailsToCql映射Tuple3[String, String, String]TupleValue,设置为java.util.Set和映射到java.util.Map.

import com.datastax.driver.core.{DataType, TupleType, Cluster}
import com.datastax.driver.core.querybuilder.QueryBuilder

import scala.collection.JavaConverters._

object Scratch extends App {

  val cluster = Cluster.builder().addContactPoint("127.0.0.1").build()
  val session = cluster.connect()

  session.execute("create keyspace if not exists emails WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };")
  session.execute("create table if not exists emails.mailing (emailaddr text PRIMARY KEY, totalmails bigint, emails map<text, frozen<set<tuple<text, text, text>>>>);")

  val emailType = TupleType.of(DataType.text(), DataType.text(), DataType.text())

  case class MailContent(addr: String, emails: Map[String, Set[Tuple3[String, String, String]]]) {
    lazy val emailsToCql = emails.mapValues {
      _.map(v => emailType.newValue(v._1, v._2, v._3)).asJava
    }.asJava
  }

  val mailContent = MailContent("test@email.com", Map(
    "dest@email.com" -> Set(("field1", "field2", "field3")),
    "dest2@email.com" -> Set(("2field1", "2field2", "2field3"))))

  val query = QueryBuilder.insertInto("emails", "mailing")
                .value("emailAddr", mailContent.addr)
                .value("totalmails", mailContent.emails.size)
                .value("emails", mailContent.emailsToCql)

  session.execute(query)

  cluster.close()
}
Run Code Online (Sandbox Code Playgroud)

这会产生一条在cqlsh中如下所示的记录:

 emailaddr      | emails                                                                                                       | totalmails
----------------+--------------------------------------------------------------------------------------------------------------+------------
 test@email.com | {'dest2@email.com': {('2field1', '2field2', '2field3')}, 'dest@email.com': {('field1', 'field2', 'field3')}} |          2
Run Code Online (Sandbox Code Playgroud)