当case类包含scala Enumeration时,如何使用Rogue与MongoCaseClassField更新mongo记录

时间:2013-06-07 20:25:01

标签: mongodb class scala record lift

我正在将Rogue 1.1.8的现有代码从2.0.0升级为lift-mongodb-record2.4-M5 to 2.5

我在编写包含scala枚举的MongoCaseClassField时遇到困难,我真的可以使用一些帮助。

例如,

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.BSONType [MyCaseClass]          .and(_。myCaseClass setTo myCaseClass)

我们曾经在Rogue 1.1.8中使用我们自己的MongoCaseClassField版本,这使得#formats方法可以覆盖。但是这个功能被包含在2.5-RC6的lift-mongodb-record中,所以我们认为这应该现在才能正常工作?

1 个答案:

答案 0 :(得分:7)

答案来自: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错误。缺点是你需要做一个 案例类的选择。

如果您想以“正确”方式执行此操作,请定义您的案例类加上a 该案例类的BSONType“见证”。要定义BSONType见证,您 需要提供从该类型到BSON类型的序列化。例如:

 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
   }
 }

那就是说,如果你为每个案件做这件事,这可能会非常麻烦 类。您的第二个选择是定义适用于任何人的通用证人 case类,如果你有一个通用的序列化方案:

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

希望这有帮助,