Исключение сериализации поля перечисления в BSON - PullRequest
0 голосов
/ 28 декабря 2018

Я использую PlayFramework 2.6 со SCALA и mongodb-драйвером.

Борьба с сериализацией Eumeration при записи.

При попытке вставить объект, содержащий поля перечисления, я получаю исключение:

Caused by: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class scala.Enumeration$Val.
at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:37)
at org.mongodb.scala.bson.codecs.macrocodecs.MacroCodec.writeValue(MacroCodec.scala:167)
at org.mongodb.scala.bson.codecs.macrocodecs.MacroCodec.writeValue$(MacroCodec.scala:162)

Я создал кодеки для самого объекта, также попытался создать кодек для типа перечислимого класса, но выглядит это правильно.

  val routeTypeCodec: CodecProvider = Macros.createCodecProvider[RouteTypeClass]
  val routeCodec: CodecProvider = Macros.createCodecProviderIgnoreNone[Route]

перечисление:

class RouteTypeClass extends TypeReference[RouteType.type]

object RouteType extends Enumeration {
  type RouteType = Value
  val Repeat, OneTime = Value
}

объект для сохранения:

case class Route(
 ...
 routeType: RouteType
 ...
);

Как записать кодек для полей перечисления, кроме определения этого поля как строки.

1 Ответ

0 голосов
/ 12 марта 2019

Откажитесь от использования перечислений.Вместо этого используйте запечатанные черты и классы случаев.Не слишком элегантное решение, но работает.

sealed trait RouteType {
  def routeType: String
}

case class Repeat() extends RouteType {
  override val routeType: String = "Repeat"
}
case class OneTime() extends RouteType {
  override val routeType: String = "OneTime"
}

objet RouteType {
  def parseFromString(value: String): Option[RouteType] = {
    Vector(Repeat(), OneTime().find(_.routeType == value)
  }
}

и написать собственный кодек BSON для этих

import org.bson.{BsonReader, BsonWriter}
import org.bson.codecs.{Codec, DecoderContext, EncoderContext}

class RouteTypeCodec extends Codec[RouteType] {
  override def encode(
    writer: BsonWriter,
    value: RouteType,
    encoderContext: EncoderContext
  ): Unit = writer.writeString(value.routeType)
  override def getEncoderClass: Class[RouteType] = classOf[RouteType]
  override def decode(reader: BsonReader,
                        decoderContext: DecoderContext): RouteType= {
    val value = reader.readString()
    val result = RouteType.parseFromString(value)
    if (result.isDefined) result.get else throw new IllegalArgumentException("No such RouteType")
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...