[mongodb] 케이스 클래스에 스칼라 열거가 포함 된 경우 MongoCaseClassField와 함께 Rogue를 사용하여 몽고 레코드를 업데이트하는 방법

기존 코드를에서 (으) Rogue 1.1.8로 업그레이드 2.0.0하고 lift-mongodb-record있습니다 2.4-M5 to 2.5.

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] 유형의 증거 매개 변수에 대한 내재 된 값을 찾을 수 없습니다. (_.myCaseClass setTo myCaseClass)

예전에는 자체 버전의를 사용하여 Rogue 1.1.8에서이 작업을 MongoCaseClassField수행 했으므로 #formats 메소드를 재정의 할 수 있습니다. 그러나이 기능은 2.5-RC6에서 lift-mongodb-record에 포함되었으므로 지금 작동해야한다고 생각 했습니까?



답변

답변 : 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
   }
 }

도움이 되었기를 바랍니다,


답변