我使用的是带有SCALA和mongodb驱动程序的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
...
);
如何为枚举字段编写编解码器,除了将此字段定义为字符串。
2条答案
按热度按时间oaxa6hgo1#
放弃使用枚举。相反,使用密封的trait和case类。不是很优雅的解决方案,但是可以工作。
并为它们编写自定义BSON编解码器
0aydgbwb2#
我已经为这个问题头疼了一段时间,并且找到了一个解决方案。这是Scala 2.13中的工作,Play 2.8
我从编写一个自定义编解码器开始,但我仍然得到了一个
Can't find a codec for CodecCacheKey{clazz=class scala.Enumeration$Val
错误。似乎编解码器注册表将识别枚举覆盖Enumeration$Value
的编解码器,但仍然找到Enumeration$Val
,即使它是一个私有类,不会直接使用。在public mongodb jira中有一个长期开放的问题。我通过创建一个扩展
CodecProvider
的类来解决此问题,该类具有Enumeration#Value
的通用编解码器,并检查scala.Enumeration$Val
和scala.Enumeration$Value
的className