Scala сериализация последовательности объектов или чего-либо еще

У меня возникла проблема с сериализацией модели: Моя модель:

case class DocumentModel(
                          documentId: Option[Int] = None,
                          title: String,
                          ...
                          responsibleList: Option[Seq[UserModel]], // No problem
                          preConditions: Option[Seq[Object]], // Problem occurs here
                          postConditions: Option[Seq[Object]] // Problem occurs here
                        )

object DocumentModel {
  implicit val documentFormat = Jsonx.formatCaseClass[DocumentModel]
}

responsibleList, preConditions, а также postConditions не хранятся в базе данных, они служат только в качестве вспомогательных списков. Я продолжаю заполнять эти списки в своем контроллере, чтобы отправить его обратно во внешний интерфейс через JSON:

val document = for {
  newDocument <- documentDTO.getDocument(documentId, clientId)
  responsibleList <- raciDocumentDTO.getResponsible_Documents(documentId)
  ...
  preConditions <- conditionController.getPreConditions(documentId)
  postConditions <- conditionController.getPostConditions(documentId)
} yield (newDocument, responsibleList, ..., preConditions, postConditions)

document.map({ case (newDocument, responsibleList, ..., preConditions, postConditions) =>
  val temp = newDocument.map(docu => {
    ...

    val doc = new DocumentModel(
      docu.documentId,
      docu.title,
      ...
      Some(responsibleList),
      Some(preConditions),
      Some(postConditions)
    )
    doc
  })

  Ok(Json.obj(
    "document" -> temp,
  ))
})

Я подозреваю, что это как-то связано с Option[Seq[Object]] или Option[Seq[Any]] в этом отношении. Компилятор выдает ошибку: Scala сериализация последовательности объектов или чего-либо еще Поскольку preConditions и postConditions могут быть instances/objects из различных models, я не могу явно указать, какой это должна быть модель. Есть ли решение этой проблемы или мне нужно идти другим путем? Заранее спасибо!

ОБНОВИТЬ

Я добавил:

trait Condition

object Condition {
  import play.api.libs.json._

  implicit val conditionWrites: Writes[Condition] = Writes[Condition] {
    case a: DocumentModel => JsObject(Seq("DocumentModel" -> Jsonx(a)))
    case b: ProcessModel => JsObject(Seq("ProcessModel" -> Jsonx(b)))
    case c: ProcessInstanceModel => JsObject(Seq("ProcessInstanceModel" -> Jsonx(c)))
  }
}

А в моих моделях:

case class DocumentModel(
                          documentId: Option[Int] = None,
                          title: String,
                          ...,
                          responsibleList: Option[Seq[UserModel]],
                          preConditions: Option[Seq[Condition]],
                          postConditions: Option[Seq[Condition]]
                        ) extends Condition

Это все еще оставляет мне это сообщение об ошибке:

Scala сериализация последовательности объектов или чего-либо еще

Scala сериализация последовательности объектов или чего-либо еще

Я впервые столкнулся с такой проблемой и, честно говоря, немного запутался.

Обновление 2

Я пробовал, как вы упомянули, но все равно вызывает ту же ошибку.

Мой код выглядит так:

Scala сериализация последовательности объектов или чего-либо еще

ОБНОВИТЬ

Я реализовал предложенные изменения и сузил проблему до следующего:

trait Condition

object Condition {
  implicit val conditionWrites: Writes[Condition] = Writes[Condition] {
    case a: DocumentModel => JsObject(Seq(
      "documentId" -> Json.toJson(a.documentId),
      "title" -> Json.toJson(a.title),
       ...
      "responsibleList" -> Json.toJson(a.responsibleList),
      "preConditions" -> Json.toJson(a.preConditions),
      "postConditions" -> Json.toJson(a.postConditions)
    ))
    case b: ...
  }

}

Когда я делаю это так, я получаю следующее сообщение об ошибке:

Scala сериализация последовательности объектов или чего-либо еще Итак, я подумал, что implicit read может отсутствовать. Итак, я добавил:

object Condition {
  implicit val conditionReads: OFormat[Condition] = Json.format[Condition] // New

  implicit val conditionWrites: Writes[Condition] = Writes[Condition] {
    case a: DocumentModel => JsObject(Seq(
      "documentId" -> Json.toJson(a.documentId),
      "title" -> Json.toJson(a.title),
      ...

Однако при запуске кода я получаю следующее:

    No unapply or unapplySeq function found
    [error]   implicit val conditionReads: OFormat[Condition] = Json.format[Condition]

Предлагаемое решение для исправления этого состояло в том, чтобы заменить мой object condition на case class condition. Однако это разрушило бы всю цель создания такого универсального trait/object.


1
782
1

Ответ:

Решено

Сделайте так, чтобы все ваши "условные" модели расширяли черту, имеющую возможность записи в JSON. Например,

trait Condition

object Condition {

  implicit val conditionWrites: Writes[Condition] = Writes[Condition] {
    case a: PreConditionA => JsObject(Seq("field" -> JsString(a.stringValue))) //or whatever
    case b: PreConditionB => //...
    //etc...
    case x: PostConditionX => //...
    case y: PostConditionY => //...
    //etc...
  }

}

case class PreConditionA(stringValue: String) extends Condition
//etc.

Затем в DocumentModel измените типы условий на признак Condition:

case class DocumentModel(
  documentId: Option[Int] = None,
  title: String,
  //...
  responsibleList: Option[Seq[UserModel]], 
  preConditions: Option[Seq[Condition]], 
  postConditions: Option[Seq[Condition]]
)

Возможно, вам придется преобразовать синтаксис сериализации к тому, что он есть для Jsonx, но, надеюсь, он достаточно похож, и вы поняли идею.