Manu Chadha
Manu Chadha

Reputation: 16745

Unable to store Scala Set with User Defined Type in Cassandra

I have the following model

case class TagPartitionsInfo (
                               year:Int,
                               month:Int
                             )

case class TagPartitions(tag:String,
                         partition_info:Set[TagPartitionsInfo])

The data in the Cassandra table is stored like follows:

tag        | partition_info
------------+--------------------------------------------------
 javascript | {{year: 2018, month: 1}, {year: 2018, month: 2}}

When I am inserting data in the table, I am getting the following error

Value 1 of type class scala.collection.convert.Wrappers$SetWrapper does not correspond to any CQL3 type

The code to insert data in the table is

def insertValues(tableName:String, model:TagPartitions):Insert = {
    QueryBuilder.insertInto(tableName).value("tag",model.tag)
      .value("partition_info",setAsJavaSet(model.partition_info))
      .ifNotExists(); 
  }

What am I doing wrong? In the console, I could see the following print which shows that my data is correct inserting in table partitions_of_a_tag with partition key List(tag) and values TagPartitions(testtag,Set(TagPartitionsInfo(2018,6)))

The table schema is

CREATE TABLE codingjedi.partitions_of_a_tag (
    tag text PRIMARY KEY,
    partition_info set<frozen<tag_partitions>>
)

tag_partitions is a UDT of type

{
   year bigint,
    month bigint
);

Upvotes: 0

Views: 341

Answers (1)

Manu Chadha
Manu Chadha

Reputation: 16745

The issue was not Set but the UDT. Cassandra doesn't know how to store the UDT value. My model has the shape of the UDT but I had to specifically create the UDT from the model as follows:

//get the definition of udt
 val partitionInfoType:UserType = session.getCluster().getMetadata.getKeyspace("myks").getUserType("tag_partitions")

//create udt value from model 
    //the logic below assumes that there is only one element in the set
    val partitionsInfo:UDTValue = partitionInfoType.newValue()
        .setLong("year",model.partition_info.head.year)
        .setLong("month",model.partition_info.head.month)


    QueryBuilder.insertInto(tableName).value("tag",model.tag)
      .value("partition_info",setAsJavaSet(Set(partitionsInfo)))

Upvotes: 1

Related Questions