0

Have been following the collection column tutorial for phantom-dsl which requires json serializer.

The implementation below is getting the following error output;

found : org.dyne.danielsan.superchain.data.models.JsonVin

[error] required: org.json4s.JValue

[error] (which expands to) org.json4s.JsonAST.JValue

[error] compact(render(obj))

Any help in pointing out where I am going wrong, much appreciated. The issue is that AFAIK phantom-dsl requires the custom type to be defined, but json4s is expecting a JValue...

import com.websudos.phantom.CassandraTable
import com.websudos.phantom.dsl._
import org.json4s.{NoTypeHints, _}
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization

case class Transaction(blockhash: String,
                       blocktime: Long,
                       confirmations: Int,
                       vout: List[Vout],
                       vin: List[Vin])

case class JsonVout(value: String,
                    n: String,
                    scriptPubKey: String)

case class JsonVin(coinbase: String,
                   sequence: String)

sealed class TransactionColumnFamily extends CassandraTable[TransactionColumnFamily, Transaction] {

  implicit val formats = Serialization.formats(NoTypeHints)

  override def fromRow(row: Row): Transaction = {
    Transaction(
      blockhash(row),
      blocktime(row),
      confirmations(row),
      vout(row),
      vin(row)
    )
  }

  object blockhash extends StringColumn(this) with PartitionKey[String]

  object blocktime extends LongColumn(this) with ClusteringOrder[Long] with Descending

  object confirmations extends IntColumn(this) with ClusteringOrder[Int] with Descending

  object vout extends JsonListColumn[TransactionColumnFamily, Transaction, Vout](this) {
    override def fromJson(obj: String): Vout = {
      parse(obj).extract[Vout]
    }

//This is where the first error arises

    override def toJson(obj: Vout): String = {
      compact(render(obj))
    }
  }

  object vin extends JsonListColumn[TransactionColumnFamily, Transaction, Vin](this) {
    override def fromJson(obj: String): Vin = {
      parse(obj).extract[Vin]
    }

//This is where the second error arises

    override def toJson(obj: JsonVin): String = {
      compact(render(obj))
    }
  }

}   

object TransactionColumnFamily extends TransactionColumnFamily with RootConnector {
  // some more stuff
  // some more stuff

}

Correction:

Thanks Flavian for the comment. You are correct. In the end this is what was needed for working with Json4s:

  object vout extends JsonListColumn[TransactionColumnFamily, Transaction, Vout](this) {
    override def fromJson(obj: String): Vout = {
      parse(obj).extract[Vout]
    }

    override def toJson(obj: Vout): String = {
      write(obj)
    }
   }

  object vin extends JsonListColumn[TransactionColumnFamily, Transaction, Vin](this) {
    override def fromJson(obj: String): Vin = {
      parse(obj).extract[Vin]
    }

    override def toJson(obj: Vin): String = {
      write(obj)
    }
  }
Community
  • 1
  • 1
dan-mi-sun
  • 551
  • 2
  • 4
  • 18

1 Answers1

0

I think your problem is that the compact(render(obj)) calls are not working as expected. The phantom examples are based on the lift-json library where that exact method call produces a string.

Most likely, your render() method expects a JValue, so what you need to do is to produce a JValue from a JsonVin before calling compact(render()). You might get away with importing import org.json4s.JsonDSL._, where there should be a render method for different kinds of objects.

Additionally, when working with the Jackson serializer, it seems you may need to provide custom serializers, as described here. If you can, just use the native one which doesn't need the extra steps.

Community
  • 1
  • 1
flavian
  • 28,161
  • 11
  • 65
  • 105