2012-08-02 59 views
0

Ø一些慣用澄清以便更好地理解:CAPA意味着地圖意味着地圖休眠的EntityManager:如何刪除協會

○層可能在不同的地圖和地圖中使用可能包含許多不同的圖層

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)及其映射(一舉成名)之間的鏈接,我已經試過:

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

您需要調用flush才能使更改在數據庫中生效。你沒有呼叫刷新,你打電話刷新,所以分貝副本覆蓋你的變化

+0

感謝您的回答,它沒有奏效。實際上,在我發佈代碼之前,我已經使用了flush。 – 2012-08-02 17:47:49

+0

你看日誌來檢查sql是否觸發數據庫?你可以使用hibernaet日誌或hibernate的show_sql或sql分析器來做到這一點。 – 2012-08-02 17:53:23

1

你的能力c是一個對象。如果您在Capa類中正確實施了hashCodeequals,則持久性提供者只能知道c實際上存在於Mapa集合中。否則,有可能的情況下,當Hibernate永遠不會知道cm確實存在,因此m.getCapas().remove(c)將永遠不會真正從m刪除c。您可以通過評估移除調用的返回值來檢查這一點。我很確定這將是false

更好的東西在這裏做的是檢查對象的主鍵,然後從集合中刪除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); 
} 

然而,這有一個額外的循環。

最好的辦法是在所有實體中實施equalshashCode方法。