0

o 一些惯用的说明以便更好地理解:capa表示mapa表示地图

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)保持不变。

感谢您的帮助。

4

2 回答 2

1

你的 Capac是一个对象。如果您在您的类中正确实现了和,持久性提供者只能知道c集合中实际存在的。否则,可能会有这样一种情况,当休眠状态永远不会知道它实际存在于中,因此永远不会真正从. 您可以通过评估 remove 调用的返回值来检查这一点。我很确定它会的。MapahashCodeequalsCapacmm.getCapas().remove(c)cmfalse

这里最好做的是检查对象的主键,然后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);   
}

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

最好的办法是在所有实体中实现equals和方法。hashCode

于 2012-08-04T22:08:19.797 回答
0

您需要调用 flush 以使更改在数据库中生效。您没有调用刷新,而是调用刷新,因此数据库副本覆盖了您的更改

于 2012-08-02T17:24:31.857 回答