Ian Juma
Ian Juma

Reputation: 107

spray-json Cannot find JsonWriter or JsonFormat type class for Class

I still get the same error, I have defined the marshaller (and imported it); it appears that the case class entry is not in context when the function is polymorphic. and this throws a Cannot find JsonWriter or JsonFormat type class for Case Class. Is there a reason why spray-json can not find the implicit marshaller for the case class, (even when defined) is this case class in context? Link to marshaller

import spray.json._
import queue.MedusaJsonProtocol._

object MysqlDb {
 ...
}

case class UserDbEntry(
  id: Int,
  username: String,
  countryId: Int,
  created: LocalDateTime
)

trait MysqlDb {
  implicit lazy val pool = MysqlDb.pool
}

trait HydraMapperT extends MysqlDb {
  val FetchAllSql: String
  def fetchAll(currentDate: String): Future[List[HydraDbRow]]

  def getJson[T](row: T): String
}

object UserHydraDbMapper extends HydraMapperT {
  override val FetchAllSql = "SELECT * FROM user WHERE created >= ?"

  override def fetchAll(currentDate: String): Future[List[UserDbEntry]] = {
    pool.sendPreparedStatement(FetchAllSql, Array(currentDate)).map { queryResult =>
      queryResult.rows match {
        case Some(rows) =>
          rows.toList map (x => rowToModel(x))
        case None => List()
      }
    }
  }

  override def getJson[UserDbEntry](row: UserDbEntry): String = {
      HydraQueueMessage(
        tableType = HydraTableName.UserTable,
        payload = row.toJson.toString()
      ).toJson.toString()
  }

  private def rowToModel(row: RowData): UserDbEntry = {
    UserDbEntry (
      id        = row("id").asInstanceOf[Int],
      username  = row("username").asInstanceOf[String],
      countryId = row("country_id").asInstanceOf[Int],
      created   = row("created").asInstanceOf[LocalDateTime]
    )
  }
}

payload = row.toJson.toString() Can't find marshaller for UserDbEntry

Upvotes: 1

Views: 1568

Answers (1)

andyczerwonka
andyczerwonka

Reputation: 4260

You have defined UserDbEntry locally and there is no JSON marshaller for that type. Add the following:

 implicit val userDbEntryFormat = Json.format[UserDbEntry]

I'm not sure how you can call row.toJson given UserDbEntry is a local case class. There must be a macro in there somewhere, but it's fairly clear that it's not in scope for the local UserDbEntry.

Edit

Now that I see your Gist, it looks like you have a package dependency problem. As designed, it'll be circular. You have defined the JSON marshaller in package com.at.medusa.core.queue, which imports UserDbEntry, which depends on package com.at.medusa.core.queue for marshalling.

Upvotes: 1

Related Questions