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记录一个用于将 A 映射到 B,另一个用于 B 到 A。

这可能吗?

更新:感谢您的所有建议。
当我尝试@Pascal 的建议时,当我尝试将元素 1 与元素 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 之前,我通过检查 Connection 表中的记录来检查元素 A 和 B 之间是否存在连接 where
((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);
}

这意味着您的要求将保持不变,当它保存时它会保存好。它不会保存两次,因为它会注意到一个是另一个的反向引用。您可能应该将其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 回答