2

私は次のクラスを持っています

public class ElementBean {
 private String link;
 private Set<ElementBean> connections;
}

要素が多対多の対称関係で相互にマップされるマップ テーブルを作成する必要があります。

@ManyToMany(targetEntity=ElementBean.class)
@JoinTable(
    name="element_elements",
    joinColumns=@JoinColumn(name="FROM_ELEMENT_ID", nullable=false),
    inverseJoinColumns=@JoinColumn(name="TO_ELEMENT_ID", nullable=false)
)
public Set<ElementBean> getConnections() {
    return connections;
}

次の要件があります

要素 A が要素 B への接続として追加されると、要素 B は要素 A の接続になるはずです。したがって、A.getConnections() は B を返し、B.getConnections() は A を返す必要があります。明示的に 2 を作成したくありません1 つは A から B へのマッピング用、もう 1 つは B から A へのマッピング用に記録されます。

これは可能ですか?

更新:すべての提案をありがとう。
@Pascal の提案を試すと、要素 1 と要素 2 を接続しようとすると、次のように 2 つのレコードが作成されます。

FROM_ELEMENT_ID、TO_ELEMENT_ID
1、2
2、1

1,2 が 2,1 と同じである場合に、レコードを対称にしたい

この問題はどのように処理されますか?

更新 マップ Bean を明示的に作成しました

class ConnectionBean {
    ElementBean from;
    ElementBean to;
}

@NotNull
@ManyToOne
@JoinColumn(name="FROM_ELEMENT_ID", nullable=false)
public ElementBean getFrom() {
    return from;
}

@NotNull
@ManyToOne
@JoinColumn(name="TO_ELEMENT_ID", nullable=false)
public ElementBean getTo() {
    return to;
}

ElementBean を更新しました

public class ElementBean {
    private String link;
    private Set<ConnectionBean> from;
    private Set<ConnectionBean> to;
}

@OneToMany(mappedBy="from", fetch=FetchType.LAZY)
public Set<ConnectionBean> getFrom() {
    return from;
}

@OneToMany(mappedBy="to", fetch=FetchType.LAZY)
public Set<ConnectionBean> getTo() {
    return to;
}

ここで、挿入と削除を制御できます。たとえば、新しい ConnectionBean を挿入する前に、接続テーブルで
((from == A && to == B) || (from == B && to == A))
挿入前。

4

3 に答える 3

2

多対多で作業する場合、Hibernate が処理してくれるので、重複についてあまり心配する必要はありません。オブジェクト モデルが一貫していることを確認する必要があり、Hibernate は必ずしもそれを支援するとは限りません。

あなたのメソッドでは、実際の接続を返すメソッドをaddConnection()持つべきgetConnections()ではなく、読み取り専用バージョンを返す必要があります。関係の両側を確実に処理する必要があります。

addConnection(ElementBean element) {
    if (element ==null) { 
        throw new IllegalArgumentException("cannot add null element"); 
    }
    connections.add(element);
    element.getConnections0().add(this);
}

これは、要件が保持され、保存すると問題なく保存されることを意味します。一方が他方の後方参照であることに気付くため、2 回保存することはありません。おそらく、getConnections0()プライベートまたはパッケージにする必要があります。

于 2010-03-23T21:38:36.620 に答える
0

これは、Hibernate の最初のレベルのキャッシュによって解決され、両側から m-2-m をマップする限り、参照を追跡します。

于 2010-03-23T19:49:55.707 に答える
0

双方向リンクを使用する場合は、両側のリンクに注意し、ドキュメントを引用する必要があります。

多くの開発者は防御的なプログラムを作成し、リンク管理メソッドを作成して、両側を正しく設定します。

したがって、あなたの場合、次のメソッドを追加することをお勧めします。

public Set<ElementBean> getConnections() {
    return connections;
}

public void setConnections(Set<ElementBean> connections) {
    this.connections = connections;
}

public void addToConnection(ElementBean connection) {
    this.getConnections().add(connection);
    connection.getConnections().add(this);
}

public void removeFromConnection(ElementBean connection) {
    this.getConnections().remove(connection);
    connection.getConnections().remove(this);
}
于 2010-03-23T22:33:52.773 に答える