Scala pickling case class versioning -


i able use scala pickling in order store binary representation of case class.

i know if there way manage versioning of case class (the way protocol buffer allows do)


here example

i make program @ date, following case class

case class messagetest(a:string,b:string)  

then serialize instance of class

import scala.pickling._ import binary._ val bytes=messagetest("1","2").pickle 

and store result file


later on, might have make evolution on case class, add new optional field

case class messagetest (a:string,b:string,c:option[string]=none) 

i able reuse data stored in file , deserialize , able recover instance of case class (with default value new parameter)

but when use following code

import scala.pickling._ import binary._ val messageback=bytes.unpickle[messagetest] 

i got following error :

java.lang.arrayindexoutofboundsexception: 26 @ scala.pickling.binary.binarypicklereader$$anonfun$2.apply(binarypickleformat.scala:446) @ scala.pickling.binary.binarypicklereader$$anonfun$2.apply(binarypickleformat.scala:434) @ scala.pickling.pickletools$class.withhints(tools.scala:498) @ scala.pickling.binary.binarypicklereader.withhints(binarypickleformat.scala:425) @ scala.pickling.binary.binarypicklereader.beginentrynotagdebug(binarypickleformat.scala:434) @ scala.pickling.binary.binarypicklereader.beginentrynotag(binarypickleformat.scala:431)


did wrong ?

is there existing way make scenario work ?

regards

well problem trying deserialize different object serialized to.

consider this. first object

scala> case class messagetest(a: string, b:string) defined class messagetest  scala> val bytes = messagetest("a", "b").pickle bytes: pickling.binary.pickleformat.pickletype = binarypickle([0,0,0,81,36,108,105,110,101,53,49,46,36,114,101,97,100,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,77,101,115,115,97,103,101,84,101,115,116,0,0,0,1,97,0,0,0,1,98]) 

now changed case object...

scala> case class messagetest(a: string, b: string, c: option[string] = none) defined class messagetest  scala> val bytes = messagetest("a", "b").pickle bytes: pickling.binary.pickleformat.pickletype = binarypickle([0,0,0,81,36,108,105,110,101,53,51,46,36,114,101,97,100,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,77,101,115,115,97,103,101,84,101,115,116,0,0,0,1,97,0,0,0,1,98,0,0,0,15,115,99,97,108,97,46,78,111,110,101,46,116,121,112,101]) 

there no way library can know mean in case because it's expecting signatures match up.

https://github.com/scala/pickling/issues/39 can @ least go 1 way it. demonstrated here.

import scala.pickling._ import scala.pickling.defaults._ import scala.pickling.binary._  case class legacymessage(a: string, b: string) case class message(a: string, b: string, c: option[string] = none)  implicit val legacyunpickler = unpickler.generate[legacymessage] implicit val messageunpickler = unpickler.generate[message]  val legacybytes = legacymessage("a", "b") val msgbytes = message("a", "b", none)  val pickledbytes = msgbytes.pickle val pickledlegacy = legacybytes.pickle  // new message can serialize legacy messages val newtoold = pickledbytes.unpickle[legacymessage]  // old messages can not serialize new message schema // println(pickledlegacy.unpickle[message])  val old = pickledlegacy.unpickle[legacymessage]  if(newtoold == old){   println(true) } 

hopefully helps little.


Comments

Popular posts from this blog

php - Submit Form Data without Reloading page -

linux - Rails running on virtual machine in Windows -

php - $params->set Array between square bracket -