[英]Exception serializing Enumeration field to BSON
我正在使用帶有SCALA和mongodb-driver的PlayFramework 2.6。
在寫時遇到枚舉序列化的問題。
當我嘗試插入包含枚舉字段的對象時,出現異常:
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
...
);
如何為枚舉字段編寫編解碼器,但將此字段定義為String除外。
刪除枚舉的使用。 而是使用密封的特征和案例類。 不太優雅的解決方案,但可行。
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")
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.