4

バックエンドで Hibernate (JPA) を使用する Scala アプリケーションを開始しています。オブジェクトをロードするために、次のコード行を使用します。

val addr = s.load(classOf[Address], addr_id).asInstanceOf[Address];

少し痛いのは言うまでもありません。次のようなヘルパー クラスを作成しました。

import org.hibernate.Session

class DataLoader(s: Session) {
  def loadAddress(id: Long): Address = {
    return s.load(classOf[Address], id).asInstanceOf[Address];
  }
  ...
}

だから、今私はこれを行うことができます:

val dl = new DataLoader(s)
val addr = dl loadAddress(addr_id)

質問は次のとおりです。これと同じパターンを使用して任意のオブジェクトをロードできる、一般的なパラメーター化されたメソッドを作成するにはどうすればよいですか? すなわち

val addr = dl load[Address](addr_id)

(またはそれらの線に沿ったもの。)

私は Scala を初めて使用するので、ここで特に恐ろしいことを許してください。

4

2 に答える 2

5

ここにあります:

import org.hibernate.Session
class DataLoader(s: Session) {
  def load[A](id: Long)(implicit m: Manifest[A]): A = {
    return s.load(m.erasure, id).asInstanceOf[A];
  }
}

編集- または、キャスト エラー (休止状態が間違ったオブジェクトを返す結果として) が内部loadで発生することを確認するには、次のようにします。

import org.hibernate.Session
class DataLoader(s: Session) {
  def load[A](id: Long)(implicit m: Manifest[A]): A = {
    return m.erasure.asInstanceOf[Class[A]].cast(s.load(m.erasure, id));
  }
}

Scala 2.8 では、次のように書くこともできます。

import org.hibernate.Session
class DataLoader(s: Session) {
  def load[A : Manifest](id: Long): A = {
    return s.load(manifest[A].erasure, id).asInstanceOf[A];
  }
}

Chrisが提案しているように、暗黙的なセッションと組み合わせることもできます。

def load[A](id: Long)(implicit m: Manifest[A], s: org.hibernate.Session): A = {
  return s.load(m.erasure, id).asInstanceOf[A];
}

A : Manifestコンテキスト ビュー表記 ( ) を追加の暗黙のパラメーターと組み合わせることはできないことに注意してください。

于 2010-03-12T17:56:40.437 に答える
3

1 つの方法は、次のjava.lang.Class.castようなことを行うためにメソッドを利用することです。

def load[A](clazz: Class[A], id: Long)(implicit s: Session) : A 
       = clazz.cast(s.load(clazz, id))

次に、使用法は次のとおりです。

implicit val s = ...//get hibernate session
val addr = load(classOf[Address], 1)

既に持っているものと大きく異なるわけではありませんが、インスタンスにアクセスするには、classインスタンスを渡す必要があります。

キャストが機能するために必要なコンパイル時にパラメータ化されたものを提供できないため、あなたが望むことを安全に行うことができないと確信しています(彼らはの消去しか提供できません)。からキャストを行うための他のメカニズムは見当たりませんManifestsClass[Address]Class[_]Manifest

もちろんasInstanceOf[A]代わりに of を使用することもできますがcast、これはコンパイル時に消去されるためisInstanceOf[Object]、コンパイル時の型チェックに関しては役に立ちません (したがって、お勧めできません)。

于 2010-03-12T15:12:26.077 に答える