首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >当case类包含scala枚举时,如何使用带有MongoCaseClassField的流氓更新mongo记录

当case类包含scala枚举时,如何使用带有MongoCaseClassField的流氓更新mongo记录
EN

Stack Overflow用户
提问于 2013-06-08 04:25:01
回答 1查看 2.1K关注 0票数 130

我正在将现有代码从Rogue 1.1.8升级到2.0.0,并从2.4-M5 to 2.5升级到lift-mongodb-record

我在编写包含scala枚举的MongoCaseClassField时遇到了困难,我真的需要一些帮助。

例如,

代码语言:javascript
复制
object MyEnum extends Enumeration {
  type MyEnum = Value
  val A = Value(0)
  val B = Value(1)
}

case class MyCaseClass(name: String, value: MyEnum.MyEnum)

class MyMongo extends MongoRecord[MyMongo] with StringPk[MyMongo] {
  def meta = MyMongo

  class MongoCaseClassFieldWithMyEnum[OwnerType <: net.liftweb.record.Record[OwnerType], CaseType](rec : OwnerType)(implicit mf : Manifest[CaseType]) extends MongoCaseClassField[OwnerType, CaseType](rec)(mf) {
    override def formats = super.formats + new EnumSerializer(MyEnum)
  }

  object myCaseClass extends MongoCaseClassFieldWithMyEnum[MyMongo, MyCaseClass](this)
  /// ...
}

当我们尝试写入此字段时,我们得到以下错误:

找不到类型为com.foursquare.rogue.BSONTypeMyCaseClass .and(_.myCaseClass setTo myCaseClass)的证据参数的隐式值

我们曾经在Rogue 1.1.8中使用我们自己的MongoCaseClassField版本来工作,这使得#formats方法可重写。但是该功能已经包含在2.5-RC6版本的lift-mongodb-record中,所以我们认为现在应该可以使用了?

EN

回答 1

Stack Overflow用户

发布于 2015-06-30 17:19:43

答案来自:http://grokbase.com/t/gg/rogue-users/1367nscf80/how-to-update-a-record-with-mongocaseclassfield-when-case-class-contains-a-scala-enumeration#20130612woc3x7utvaoacu7tv7lzn4sr2q

但更方便的是直接在StackOverFlow上使用:

抱歉,我应该早点来的。

Rogue的一个长期存在的问题是,很容易意外地生成一个不能序列化为BSON的字段,并在运行时(当您试图将该值添加到DBObject中时)而不是在编译时失败。

为了解决这个问题,我引入了BSONType类型的类。优点是它可以在编译时捕获BSON错误。缺点是,当涉及到case类时,您需要做出选择。

如果您想以“正确”的方式完成此操作,请定义case类以及该case类的BSONType“见证者”。若要定义BSONType见证服务器,需要提供从该类型到BSON类型的序列化。示例:

代码语言:javascript
复制
 case class TestCC(v: Int)

 implicit object TestCCIsBSONType extends BSONType[TestCC] {
   override def asBSONObject(v: TestCC): AnyRef = {
     // Create a BSON object
     val ret = new BasicBSONObject
     // Serialize all the fields of the case class
     ret.put("v", v.v)
     ret
   }
 }

也就是说,如果你为每个案例类都这样做,这可能是相当繁重的。如果您有一个通用序列化方案,那么您的第二个选择是定义一个适用于任何案例类的通用见证:

代码语言:javascript
复制
 implicit def CaseClassesAreBSONTypes[CC <: CaseClass]: BSONType[CC] =
new BSONType[CC] {
   override def asBSONObject(v: CC): AnyRef = {
     // your generic serialization code here, maybe involving formats
   }
 }

希望这能帮上忙

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16992382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档