2010-03-23 34 views
1

引用对称休眠映射表我有下面的类自使用@ManyToMany

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

我需要创建,其中元件在许多一对多对称关系彼此映射的映射表。

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

我有以下要求

当元素A被添加为元件B的连接,然后元件B应该成为元件A的所以A.getConnections(连接)应返回B和B .getConnections()应该对于B返回答:我不想明确创建2只记录一个映射A到B,另一个A.

这可能吗?

更新:谢谢你的所有建议。
当我尝试@帕斯卡的建议下两个记录被创建时,我尝试元件1件2

FROM_ELEMENT_ID连接如下,TO_ELEMENT_ID
1,2
2,1

我想记录是对称的,其中1,2是一样的2,1

这个问题是如何处理的?

更新 我明确创建的地图豆

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之前,我通过检查连接表中是否存在元素A & B之间的连接来检查是否存在连接表,其中
((from == A & & to == B)||(from == B & &为== A))
插入前。

回答

1

当多对多的工作,你不必太担心重复,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()为private或package。

+0

@Michael - 不确定'ready only version'是什么意思。你建议用getConnections'0'()来覆盖getConnections()吗?我没有为element_elements定义一个DAO类,它是通过休眠来处理的。你能否详细说明一下? – smahesh 2010-03-24 20:37:31

+1

首先,您应该配置hibernate而不是使用方法访问的字段访问。字段访问意味着hibernate将直接写入该字段,而不是通过该方法。这将允许您自定义该方法。 多对多和多对一的问题始终是反向参考。如果某人只添加了前向引用而没有添加后向引用,那么您的对象模型将会不同步。 这就是为什么您通过getConnections返回集合的只读版本的原因。所以当他们想要添加一些东西时,他们被迫使用你的受控方法 – 2010-03-29 13:18:35

0

这将通过Hibernate的一级缓存来解决跟踪引用的,只要你从两侧映射M-2-M。

+0

@cws - 这里没有发生。 – smahesh 2010-03-24 20:29:45

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); 
} 
+0

@Pascal - 查看更新的评论。 – smahesh 2010-03-24 20:22:12