当案例类包含scala枚举时,如何使用带有Rogue的MongoCaseClassField更新mongo记录


129

我从升级现有的代码Rogue 1.1.8,以2.0.0lift-mongodb-record2.4-M5 to 2.5

我在编写MongoCaseClassField包含scala枚举的过程中遇到困难,我确实可以使用一些帮助。

例如,

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]的证据参数的隐含值。并且(_.myCaseClass setTo myCaseClass)

我们过去使用Rogue 1.1.8来运行此功能,方法是使用自己的版本MongoCaseClassField,从而使#formats方法可重写。但是该功能已包含在2.5-RC6的lift-mongodb-record中,所以我们认为现在应该可以使用?


9
看起来在流氓用户列表上提供了答案:grokbase.com/t/gg/rogue-users/1367nscf80/…–
Asya Kamsky

Answers:


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错误。不利的一面是,在案例类方面,您需要做出选择。

如果要以“正确”的方式执行此操作,请定义您的案例类以及该案例类的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
   }
 }

也就是说,如果您为每个案例类都这样做,那么可能会很麻烦。您的第二个选择是定义一个通用见证人,该见证人适用于任何案例类(如果您具有通用序列化方案):

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

希望这可以帮助,

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.