Domanda

I have a hierarchy like the following:

case class A(val a: Long, val b: String)

case class B(val c: String) extends A(a=3, b="a string")

and I'm trying to serialize it using lift-json ala the following:

val obj = B(c="another string")
val cameraJson = net.liftweb.json.Serialization.write(obj)

but what I'm seeing is that it only serializes the properties in class B and not those in A.

I've also tried:

compact(render(decompose(obj)))

with the same result

What gives? Is there something obvious in Scala that I'm missing?

È stato utile?

Soluzione

case class inheritance is a deprecated feature of Scala. This should work for instance:

trait A { val a: Long; val b: String }
case class B(a: Long = 3, b: String = "a string", c: String) extends A

val obj = B(c="another string")
var ser = Serialization.write(obj)
Serialization.read[B](ser)

Altri suggerimenti

Classic lift JSON serialisation for case classes is based on constructor argument list (see decompose implementation), not class attributes. So you have to either override all fields declared in the parent trait (as in the @Joni answer) or use composition instead of inheritance.

For example:


case class A(a: Long, b: String)
case class B(c: String, a: A = A(a=3, b="a string"))
B(c="another string")

BTW val keyword in case class constructor is unnecessary. The accessors for every constructor arg is one of the things you are getting for free by declaring class as a case.

IMO serializing only c seems like the right thing to do. The info appearing in serialization will be that the type is B and the value of C. Values of a and b are implied by the info type is B. They are 3 and "a string", and can be nothing else, so they do not need to be written.

From maybe too cursory a look at the source code, the default behavior of is to serialize fields that correspond to parameters of the primary constructor

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top