0

私のエンティティ(myGroup : Group)には、コレクションプロパティ(members : HashMap<Long, GroupMember>)があり、ユーザーが複数の新しい(永続化されていない)GroupMembermyGroup.membersマップに追加できるようにしたいです。

  • コレクションプロパティにハッシュマップを使用している理由は、コレクションの使用が実行可能であることを確認するためです(つまりGroupMember、ビジネスロジックの実行中にIDをすばやく複数回取得できる必要があります)。

  • それらをすぐに永続化したくない理由は、追加の復帰をサポートするためです。ユーザーは、マップを操作し、満足するまでメンバーを追加および削除してから、永続化できる必要がありますmyGroup.members(Hibernateセッションでエンティティを保存してフラッシュする)。

問題は、Hibernateが未保存であることを検出するために新しいGroupMembersにゼロのIDを割り当てる必要があることです。(*)メンバーはマップ内にあり、IDでキー設定されているため、どちらの前にも1つの新しいメンバーしか追加できません。保存または元に戻します。IDがゼロの2番目の新しいメンバーを追加すると、最初のメンバー(への参照)が単純にオーバーライドされます。

私の質問myGroup.membersは、ハッシュマップまたは他のマップ/辞書を使用することのパフォーマンス上の利点を維持しながら、コレクション()への複数の未保存エンティティの追加をサポートするためにコードソリューションをどのように最適に適応させることができるかです。

注:IDがインスタンス内のデータの一意の組み合わせから派生しGroupMember、保存の直前に、Hibernateが永続化する必要があることを検出するために、IDがゼロに設定されるハックをすでに試しましたが、エレガントではなく、私はそれが確実に機能する方法を見つけていません。

*この点に関するHibernateの動作を完全には理解していません。

Group以下のエンティティの省略コード:

@Entity
@Table (name="GROUP")
public class Group
{
    private Map<Long,GroupMember> members = new HashMap<Long,GroupMember>();

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "ownerGroup", cascade = { CascadeType.ALL })
    @MapKey(name="id")
    public Map<Long,GroupMember> getMembers() { return this.members; }

    public void setMembers(Map<Long,GroupMember> members) { this.members = members; }

    // ...other properties and methods...
}
4

1 に答える 1

1

あなたが何を達成しようとしているのか、私は少し混乱しています。永続化されていないメンバーには ID がありません。IDをキーとして使用しているため、これらのメンバーの「ルックアップ」動作は何を期待していますか? 新しいメンバーはまだ ID を持っていないため、ID で新しいメンバーを検索できるのは合理的ではないように思えます。

新しいメンバーを検索する必要がない場合は、次のことをお勧めします。

  1. 「新しいメンバー」を格納する別の属性
  2. エンティティにメソッド commit() と revert() がある
  3. ユーザーは更新が完了すると commit() を呼び出し、新しいエンティティは実際の永続性のために実際の「マップされた」マップ/リストに移動されます

新しいメンバーのルックアップが必要であり、あなたの文章から、証明済みの一意のキーを自分で生成できるように思われる場合、休止状態で ID を生成しないことを検討しますか? Hibernate には、ID が Hibernate によって (代理キーとして) 生成され、ユーザーによって提供される (一種の自然キー) かどうかを決定するオプションがあります。IDを代理キーとして扱っていないように見えるので、あなたの場合は自己提供IDの方が適していると思います。


編集:個別に保存できない理由についてのOPからのコメントに関しては、このアプローチで簡単に解決できます(そして、それもより理にかなっていると思います):

(プセドコード)

class Group {
  private List<Member> members;  // mapped in hibernate
  private List<Member> unsavedMembers;  // unmapped

  public Map<Long, Member> getProposedMemberMap() {
    // returned the combined "view" members and unsavedMembers
  }

  @PreUpdate  // you may consider running it it pre-update too
  public void commit() {
    members.addAll(unsavedMembers);
    unsavedMembers.clear();
  }

  public void revert() {
    unsavedMembers.clear();
  }
}

そうすることで、実際のメンバーと保存されていないメンバーを別々に保存しながら、反復する「提案されたメンバー」のビューを取得できます。

于 2012-06-27T03:27:44.163 に答える