Spark Scala读取Cassandra中Set类型数据时类型不匹配问题求助
解决Cassandra Java Driver读取Set到Scala Case Class的类型不匹配问题
问题根源
Cassandra Java Driver的row.getSet()方法返回的是Java集合框架的java.util.Set[String],而你的Scala case class中定义的status字段是Scala原生的scala.collection.immutable.Set[String],两者属于不同的集合体系,因此触发类型不匹配错误。
解决方案
需要将Java的Set转换为Scala的immutable Set,以下是两种常用实现方式:
方式1:使用scala.jdk.CollectionConverters(Scala 2.13+推荐)
Scala 2.13及后续版本官方推荐用scala.jdk.CollectionConverters完成Java与Scala集合的互转:
import scala.jdk.CollectionConverters._ // 读取并转换Set Option(row.getSet("customer_status", classOf[String])) .map(javaSet => javaSet.asScala.toSet)
方式2:使用scala.collection.JavaConverters(旧版本兼容)
如果项目基于Scala 2.12及更早版本,可使用JavaConverters:
import scala.collection.JavaConverters._ // 读取并转换Set Option(row.getSet("customer_status", classOf[String])) .map(_.asScala.toSet)
完整修改后的getData方法
import scala.jdk.CollectionConverters._ def getData(id: String): Option[test] = { try { val result = session.execute( s"SELECT * FROM $Keyspace.table WHERE id=?", id ) if (result.getAvailableWithoutFetching != 1) { logger.error(s"Failed to find $id") None } else { val row = result.one() Some(test( id, Option(row.getSet("customer_status", classOf[String])) .map(_.asScala.toSet) )) } } catch { case e: IllegalArgumentException => logger.error(s"Requested column names incorrect when attempting to get customer record: $e") None case e: Exception => logger.error(s"Exception in getting customer record for customer $id: $e") None } }
额外优化建议
- 避免在Scala case class中使用
var,推荐用val保持不可变性,符合Scala设计理念:case class test( id: String, status: Option[Set[String]] = None ) - 确保导入正确的集合转换工具类,避免混淆不同版本的API。
内容的提问来源于stack exchange,提问作者Programmer
相关产品推荐
相关产品推荐

