Hibernate級聯操做 註解


EJB3 支持的操做類型java

 

/**
 * Cascade types (can override default EJB3 cascades
 */
public enum CascadeType {
	ALL,
	PERSIST,
	MERGE,
	REMOVE,
	REFRESH,
	DELETE,
	SAVE_UPDATE,
	REPLICATE,
	/** @deprecated use @OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true) */
	@Deprecated
	DELETE_ORPHAN,
	LOCK,
	/** @deprecated use javax.persistence.CascadeType.DETACH */
	@Deprecated
	EVICT,
	DETACH
}

 

 

級聯更新保存session

 

 @JoinColumn(name = "conf_file_id", referencedColumnName = "conf_file_id",insertable = true,updatable = true)
    @Cascade(value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})


級聯刪除app

 

 

  @OneToMany(mappedBy = "projectByProPlanId",orphanRemoval=true)
    @Cascade(value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})

 

 

save-update: 級聯保存(load之後若是子對象發生了更新,也會級聯更新). 但它不會級聯刪除
delete: 級聯刪除, 但不具有級聯保存和更新
all-delete-orphan: 在解除父子關係時,自動刪除不屬於父對象的子對象, 也支持級聯刪除和級聯保存更新.
all: 級聯刪除, 級聯更新,但解除父子關係時不會自動刪除子對象. 
ide

delete-orphan:刪除全部和當前對象解除關聯關係的對象 性能

 

注意:以上設在哪一段就是指對哪一端的操做而言,好比delete,若是設在one的一端的<set>屬性裏,就是當one被刪除的時候,自動刪除全部的子記錄;this

若是設在many一端的<many-to-one>標籤裏,就是在刪除many一端的數據時,會試圖刪除one一端的數據,若是仍然有many外鍵引用one,就會報「存在子記錄」的錯誤;若是在one的一端同時也設置了cascade=「delete」屬性,就會發生很危險的狀況:刪除many一端的一條記錄,會試圖級聯刪除對應的one端記錄,由於one也設置了級聯刪除many,因此其餘全部與one關聯的many都會被刪掉。編碼

因此,千萬謹慎在many一端設置cascade=「delete」屬性。spa

故此cascade通常用在<one-to-one>和<one-to-many>中.net


如下轉載自:http://blog.csdn.net/sinlff/article/details/7342527hibernate

不少人對持久層概念搞不清JPA、Hibernate、EJB3.0的關係,這裏作一下簡單的說明:JPA是一個持久層設計接口,EJB3.0和Hibernate是具體的實現類,EJB3.0和Hibernate的功能近似相等的(Hibernate沒有Session Bean,Spring MVC3的SessionAttribute跟Session Bean近似)。

理論是使用JPA接口能夠無縫切換持久層實現,可是僅僅是理論上!!!


JPA是在Hibernate成熟並大行其道的時候才推出的,基本上是借鑑Hibernate的優勢,作了一個統一的標準而已,JPA1.0沒有一對多的級聯刪除配置,也許JPA2.0裏纔有吧(這裏沒作過調研)
@OneToMany(mappedBy = "commentTeam")
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
private Set<CommentTeamMember> commentTeamMembers;
這裏爲了說明,只貼出一對多的關鍵代碼,其它無關的註解已忽略掉,以避免形成干擾。
這裏重點說明一下四個經常使用的註解配置的區別:
CascadeType.SAVE_UPDATE
CascadeType.ALL
CascadeType.DELETE
CascadeType.DELETE_ORPHAN


 之全部之列出這四個,是由於我不想跟書本上把全部的概念都羅列出來。基本上開發時其中的3個都以及足夠用了,下面我結合代碼演示一下他們之間的區別,以及使用的時候注意的地方。
CascadeType.SAVE_UPDATE:Hibernate專有的,JPA並不支持,做用是級聯保存、級聯更新(注:JPA很噁心,要麼你配置
CascadeType.ALL,要麼你配CascadeType.SAVE+CasadeType.Merge。八卦一句:專家雖牛,多年不寫代碼,定的標準讓編碼麻煩呀!)
CascadeType.ALL:級聯保存、修改、刪除、同步,通常不多用,看看控制檯的一長串SQL就知道性能低下,你沒改的關聯表也給你發update語句,我歷來沒用過這個屬性。
CascadeType.DELETE:當調用session.delete(A)的時候,級聯刪除關聯的對象。(注:先調用A.setB(null),再調用session.delete(A),這樣是級聯刪不掉B的。
CascadeType.DELETE_ORPHAN:一對多級聯刪除。


下面重點來講說這個CascadeType.DELETE_ORPHAN:
看過API、開發指南,級聯刪除就一個經典的
@OneToMany(mappedBy = "commentTeam")
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.DELETE_ORPHAN})
private Set<CommentTeamMember> commentTeamMembers;


mappedBy不可少,映射A->B一對多的另外一邊控制反轉(誰控誰的問題),新版的Hibernate3.4中配置更簡單,變一句了,更簡潔吧?
@OneToMany(mappedBy = "commentTeam",orphanRemoval=true) 

private Set<CommentTeamMember> commentTeamMembers;


CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
commentTeam.setCommentTeamMember(null);//想級聯刪除子表數據
this.getHibernateTemplate.saveOrUpdate(commentTeam);
這樣級聯刪除卻沒有發生,爲何呢?
再來一個例子
CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
Set<CommentTeamMember> commentTeamMembers=new HashSet<CommentTeamMember>();
commentTeam.setCommentTeamMember(commentTeamMembers);//想級聯刪除子表數據或增減替換對象
this.getHibernateTemplate.saveOrUpdate(commentTeam);
這個例子級聯刪除的效果也沒發生!即便commentTeamMembers裏有若干個對象。


成功執行級聯刪除的語法:
CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
commentTeam.getCommentTeamMember().clear();//注意這裏引用的集合仍是原來的集合,這裏沒有從新new過
commentTeam.getCommentTeamMember().add(new CommentTeamMember());//若是想替換爲新的集合能夠用addAll方法
this.getHibernateTemplate.saveOrUpdate(commentTeam);

分析一下緣由:級聯刪除起做用的前提是關聯的集合對象不能從新指向新的引用,必須在原有的集合裏操做新增、刪除、清空元素,像上面的setXXX(null)的方法等是起不到級聯刪除做用的,大概是Hibernate自認本身原生的集合對象吧,本身New的放進行級聯刪除無效!

相關文章
相關標籤/搜索