2

User オブジェクト (user_from および user_to) に関連付けられた Message オブジェクトがあります。Hibernate (JPA アノテーション付き) を使用して Message インスタンスをデータベースに永続化し、user_id を永続化します。

User オブジェクトもデータベースに保存されますが、メッセージを取得するときは、データベースからではなくメモリ内の Map から User を取得したいと考えています。

その理由は、データベース (Facebook データ) に永続化できないいくつかの一時的な属性があり、Facebook データが既にメモリに読み込まれている場合、Facebook にデータを再クエリしたくないためです。

これは可能ですか、または UserType を作成することによって行う必要がありますか? UserType、Message、User、またはカスタム マッパーとして定義する必要があるクラスはどれですか? カスタムマッパーの場合、JPA アノテーションを使用してマッパーを関連付けるにはどうすればよいですか (構成を使用して meta-type="com.example.hibernate.customtype.CustomerTypeMapper" を設定する例を見ました)

ご助力ありがとうございます!

ユーザークラス:

@Entity(name="com.company.model.user")
@Table(name = "user")
public class User {
    private Long id;
    private Long fbId;
    private String firstName;
    private URL picThumbnailUrl;
    //...

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Long getFbId() {
        return fbId;
    }
    public void setFbId(Long fbId) {
        this.fbId = fbId;
    }
    @Transient @FacebookField
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    @Transient @FacebookField
    public URL getPicThumbnailUrl() {
        return picThumbnailUrl;
    }
    public void setPicThumbnailUrl(URL picThumbnailUrl) {
        this.picThumbnailUrl = picThumbnailUrl;
    }
    //....
}

メッセージ クラス:

@Entity(name="com.company.model.message")
@Table(name = "message")
public class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ManyToOne
    @JoinColumn(name="user_id_from")
    private User from;
    @ManyToOne
    @JoinColumn(name="user_id_to")
    private User to;
    private String text;
    //...

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public User getFrom() {
        return from;
    }
    public void setFrom(User from) {
        this.from = from;
    }
    public User getTo() {
        return to;
    }
    public void setTo(User to) {
        this.to = to;
    }
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }
    //....
}
4

3 に答える 3

1

EntityListenerまたは@PostLoadコールバックメソッドを使用します。

@PostLoad
public void updateFacebookFields() {
  // get stuff from HashMap
  setFirstName("whatever");
  setPicThumbnailUrl(myUrl);
}

更新(以下のコメントに基づく):

メモリからインスタンスをロードしたいのは理解できます。なぜHibernateにそれを実行させたいのかわかりません:-)それはすべて本当に単純な選択に帰着します-エンティティには、データベースに常に保持/ロードしUserたいフィールドが少なくともいくつかあるか、そうではありません。前者は私が上で提案したソリューションによって最もよく提供されるため、後者のシナリオについて話していると思います。次に、選択内容は次のようになります。

  1. まったく持続Userしない。それを参照するエンティティは、ユーザー識別子のみを保持します。適切なgetterメソッドを使用して、キャッシュから実際のユーザーインスタンスを取得します。

  2. 上記を自動化するカスタムタイプを作成できます。これは、ユーザーを参照するエンティティが多数ある場合に意味があります(コードの繰り返しを避けることができます)。UserTypeインターフェースを実装する必要があります。ResultSetで渡された識別子に基づいて、メソッドUser内からキャッシュからインスタンスを取得します。nullSafeGet()で反対のことをして、nullSageSet()それを元に戻します。

于 2009-09-07T19:38:42.683 に答える
0

単純性の原則を使用して、私は次のことを提案することから始めます。

必要に応じてユーザーを永続化しながら、ユーザーエンティティをロードせずにメッセージを確実にクエリできます。私が行うことは、Longと入力されたUserIdフィールド(正しく理解している場合は「to」と「from」)を使用することです。したがって、どのユーザーが関連しているかを示す情報があります。

ここで、実際のユーザーエンティティを取得するには:

  • マップを調べることで、ユーザーインスタンスを提供する代替ゲッター(一時的、Hibernate用にマップされていない)を作成できます。

ドメインモデルオブジェクト(ここでは永続エンティティ)がサービスやその他のコードにアクセスするのを制限するのが一般的です。したがって、マップをモデルの一部にします(モデルクラスに静的に格納できます)。

  • または、他のコード(サービスなど)がUserIdを使用して、適切なサービス(マップをカプセル化する)を呼び出すことにより、UserIdを介してUserインスタンスを取得できるようにします。
于 2009-09-07T19:35:57.507 に答える
0

この場合、ユーザータイプは役に立たないと思います。ユーザータイプは、データがデータベースに保存される方法を指定するためのものではなく、データベースに保存される方法を指定するためのものです。

おそらく最も簡単な解決策は、フィールドを一時的なものとしてマークし、ゲッターにサービスからこのデータをフェッチさせ、内部キャッシュをチェックし、キャッシュミスの場合は実際にFacebookにクエリを実行することです。

永続化されたフィールドのように処理したいのですが、休止状態のイベントモデルをチェックして、ロジックをプラグインするために実装する必要のあるイベントを見つける必要があります。 DBやXMLファイルとは異なるもので永続化する多かれ少なかれ完全な永続化ソリューション。

于 2009-09-07T19:22:41.823 に答える