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)保持不变。
感谢您的帮助。
答案 0 :(得分:1)
你的Capa c
是一个对象。如果您已在c
类中正确实施Mapa
和hashCode
,则持久性提供程序只能知道equals
集合中实际存在的Capa
。另外,可能有一种情况,当hibernate永远不会知道c
中m
实际存在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拷贝覆盖你的更改