0

Below is the simplified code that has a Map with key and value as case class. Key and value object are successfully serialized with circe. But facing challenge to serialize Map[CaseClassKey, CaseClassValue] with circe.

//////case classes and common vals starts here//////

case class Person(personId : Int, phoneNumber : Int)

case class Item(name : String)
case class Basket(items : List[Item], bills : Map[Int, Int])

def createBasketInstance() : Basket = {
    val milk = Item("milk")
    val coffee = Item("coffee")

    val bills = Map(1 -> 20, 2 -> 75)
    Basket( List(milk, coffee), bills )
}

val basket = createBasketInstance()
val person = Person(1, 987654)

//////case classes and common vals ends here//////



import io.circe._
import io.circe.generic.semiauto._
import io.circe.syntax._
import io.circe.parser._

//Serializing Person instance that is used as Key in Map
{
    implicit val personCodec :Codec[Person] = deriveCodec[Person]
    val jsonString = person.asJson.spaces2
    println(jsonString)
    
}

println("-" * 50)

//Serializing Basket instance that is used as Value in Map
{
    implicit val itemCodec :Codec[Item] = deriveCodec[Item]
    implicit val basketCodec :Codec[Basket] = deriveCodec[Basket]
    val jsonString = basket.asJson.spaces2
    println(jsonString)
}

println("-" * 50)

//Serializing Map[Person, Basket]
//TODO : not able to make it work
{
    implicit val itemCodec :Codec[Item] = deriveCodec[Item]
    implicit val basketCodec :Codec[Basket] = deriveCodec[Basket]
    
    val map = Map(person -> basket)

    //TODO : How to make below lines work
    
    //val jsonString = map.asJson.spaces2
    //println(jsonString)
}

scalafiddle link : https://scalafiddle.io/sf/SkZNa1L/2

Note : Looking to just serialize and deserialize data (Map[Person, Basket]) correctly. How json looks is not really important in this particular case.

mogli
  • 1,549
  • 4
  • 29
  • 57
  • 1
    How do you want that JSON to look? Field names in JSON have to be strings. – Thilo Feb 26 '21 at 12:36
  • @Thilo : Looking to just serialize and deserialize data (Map[Person, Basket]) correctly. How json looks is not really important in this particular case. – mogli Feb 26 '21 at 13:21
  • 1
    @mogli How it looks is very important because you need to understand how your serialization format works to design the best way to serialize it. Is like thinking it doesn't matter how a database works because I only want to save data there without worrying about how to transform your data into tables / documents / graphs or whatever you are using. – Luis Miguel Mejía Suárez Feb 26 '21 at 13:50

1 Answers1

3

Strictly speaking, you are trying to create an invalid json. Json map structure isn't an arbitrary map, it's an object structure where keys are property names. https://www.json.org/json-en.html

See also Can we make object as key in map when using JSON?

Update:

I suggest a slight change to your model to get the job done. Instead of Map use array of objects, each having two properties: key and value

Something like this:

case class Entry(key: Person, value: Basket)

So you can replace Map[Person, Basket] with Seq[Entry], and convert it back to Map if needed.

tentacle
  • 543
  • 1
  • 3
  • 8