1

ケースクラスを使用して、アプリ内のデータのさまざまな「モデル」を定義しています。理由は、Jerkson(JacksonへのScalaインターフェース)を簡単に使用できるようにするためです。UserRiakでドメインオブジェクトに変換するため@RiakKeyに、GUIDのアノテーションを使用しました。私は次のものを持っています:

case class User(
  @RiakKey val guid: String,

  @RiakIndex(name = "email") val email: String,

  val salt: String,

  val passwordHash: String,

  val emailHash: String,

  val firstName: String,

  val lastName: String,

  val suspended: Boolean=false,

  val created: Timestamp=now

)

ケースクラスでドメイン変換を実行しようとすると、@RiakKeyが認識されません。をスローしNoKeySpecifedExceptionます。これが私のコンバーターです:

class UserConverter(val bucket: String) extends Converter[User] {

  def fromDomain(domainObject: User, vclock: VClock) = {
    val key = getKey(domainObject)

    if(key == null) throw new NoKeySpecifedException(domainObject)

    val kryo = new Kryo()
    kryo.register(classOf[User])

    val ob = new ObjectBuffer(kryo)
    val value = ob.writeObject(domainObject)

    RiakObjectBuilder.newBuilder(bucket, key)
        .withValue(value)
        .withVClock(vclock)
        .withContentType(Constants.CTYPE_OCTET_STREAM)
        .build()
  }
}

これは、Javaアノテーションを使用するScalaの問題ですか?回避策はありますか?

アップデート

Userオブジェクトが作成および保存される場所と、コンバーターが参照される場所は次のとおりです。

1)

val user = parse[User](body) // jerkson parse, body is a string of JSON
User.store(user)

2)

object User {

  val bucketName = "accounts-users"
  val bucket = DB.client.createBucket(bucketName).execute()

  def fetch(id: String) = bucket.fetch(id).execute().getValueAsString()

  def store(o: User) = bucket.store( o ).withConverter(new UserConverter(bucketName)).execute()

}

スタックトレース

com.basho.riak.client.convert.NoKeySpecifedException
        at com.basho.riak.client.bucket.DefaultBucket.store(DefaultBucket.java:455)
        at com.threetierlogic.AccountService.models.User$.store(User.scala:58)
        at com.threetierlogic.AccountService.controllers.Users$$anonfun$routes$3.apply(Users.scala:54)
        at com.threetierlogic.AccountService.controllers.Users$$anonfun$routes$3.apply(Users.scala:51)
4

2 に答える 2

2

(この回答の前に長い会話をして申し訳ありません)

scala についてもう少し学んだ後、ケース クラスでは少し違ったやり方をしなければならないことがわかりました。

http://piotrbuda.eu/2012/10/scala-case-classes-and-annotations-part-1.html

もしあなたがそうするなら:

@(RiakKey@field) guid: String

できます。

私は小さなテスト プログラムを scala で作成し、null を返し、例外をスローさせる静的getKey()メソッドを使用して、注釈付きのキーを抽出することができました。DefaultBucket

import com.basho.riak.client.convert.KeyUtil.getKey;

object Main {

  def main(args: Array[String]): Unit = {
    val u = User("my_key")
    val k = getKey(u)
    System.out.println(k);

  }
}

User.scala

/* scala 2.9.1 would be scala.annotation.target.field */
import scala.annotation.meta.field
import com.basho.riak.client.convert.RiakKey;

case class User (@(RiakKey@field) guid: String)

出力:

私の鍵

(そして、アノテーションを元の状態に戻すと、期待どおりに戻りますnull)

于 2013-02-06T20:34:27.843 に答える
0

これが私が提案する問題の回避策です。注釈に頼るのではなく、DefaultBucket.storeメソッドを使用して手動でキーを指定します。

私のユーザー コンパニオン オブジェクト:

object User {

  val bucketName = "accounts-users"
  val bucket = DB.client.createBucket(bucketName).execute()

  def store(key: String, o: User) = bucket.store(key, o).withConverter(new UserConverter(bucketName)).execute()

}

そしてそれを使用して:

val user = parse[User](body)
User.store(user.guid, user)
于 2013-02-06T18:05:11.450 に答える