Hibernate EntityManager:如何删除关联

时间:2012-08-02 17:04:17

标签: hibernate many-to-many associations entitymanager

o为了更好地理解一些惯用的说明: capa 表示图层图钉表示地图

o图层可能在不同的地图中使用,地图可能包含许多不同的图层

o删除图层时,与地图的关联必须消失,但地图本身会继续存在。

o相反,当您删除地图时,与图层的关联必须消失,但图层本身会继续存在。

o映射代码:

@Entity
@Table(name = "CAPA")
public class Capa implements Serializable {    
    @ManyToMany(fetch=FetchType.LAZY, mappedBy="capas")
    private Set<Mapa> mapas;
}

@Entity
@Table(name = "MAPA")
public class Mapa implements Serializable {
    @ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name="mapa_capa", joinColumns={@JoinColumn(name="idMapa")}, inverseJoinColumns={@JoinColumn(name="idCapa")}) 
    private Set<Capa> capas;
}

o要删除图层(capa)与其地图(mapas)之间的链接,我尝试过:

Capa c = findCapa();
Iterator<Mapa> itms = c.getMapas().iterator();        
while (itms.hasNext()) {
    Mapa m = itms.next(); 
    m.getCapas().remove(c);
    c.getMapas().remove(m);
    getEntityManager().refresh(m);                
    getEntityManager().refresh(c);   
}

这不起作用。两个集合(m.capas和c.mapas)保持不变。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

你的Capa c是一个对象。如果您已在c类中正确实施MapahashCode,则持久性提供程序只能知道equals集合中实际存在的Capa。另外,可能有一种情况,当hibernate永远不会知道cm实际存在m.getCapas().remove(c)因此c永远不会从m中删除false。您可以通过评估remove调用的返回值来检查这一点。我很确定它会是actual object

这里更好的做法是检查对象的主键,然后从集合中删除Capa c = findCapa(); Iterator<Mapa> itms = c.getMapas().iterator(); while (itms.hasNext()) { Mapa m = itms.next(); foreach(Capa c1 : m.getCapas()) { if(c1.getId().equals(c.getId())) { m.getCapas().remove(c1); } } //No need to remove m from c as Mapa is the owning side getEntityManager().refresh(m); getEntityManager().refresh(c); }

equals

然而,这有一个额外的for循环。

最好的办法是在所有实体中实施hashCode和{{1}}方法。

答案 1 :(得分:0)

您需要调用flush以使更改在数据库中生效。你没有调用flush,你调用刷新,所以db拷贝覆盖你的更改