There are a few things you are going to need to overcome here:
- Converting the map into the java.util.Map type. (You've already covered this by using mapAsJavaMap)
- Converting the Set[Tuple3] into a java.util.Set type.
- Converting Tuple3 into a TupleValue.
Unfortunately the error returned by the driver (java.lang.IllegalArgumentException: Value 1 of type class scala.collection.convert.Wrappers$MapWrapper does not correspond to any CQL3 type) is misleading, as the Map type is converting correctly in your code, but the Tuple3 type is ultimately what it is having problems with. I opened up JAVA-833 to track this.
I'm making assumptions about what MailContent is, but here is some code that should make things work. The main logic that does the heavy lifting is emailsToCql which maps Tuple3[String, String, String] into TupleValue, Set to java.util.Set and Map to 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("[email protected]", Map(
"[email protected]" -> Set(("field1", "field2", "field3")),
"[email protected]" -> 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()
}
This yields a record that looks like the following in cqlsh:
emailaddr | emails | totalmails
----------------+--------------------------------------------------------------------------------------------------------------+------------
[email protected] | {'[email protected]': {('2field1', '2field2', '2field3')}, '[email protected]': {('field1', 'field2', 'field3')}} | 2